// Copyright 2014 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"testing"
)

// shiftProg adjusts the addresses in p.
// It adds vdelta to all virtual addresses and fdelta to all file offsets.
func shiftProg(p *Prog, vdelta Addr, fdelta Addr) {
	p.Entry += vdelta
	for _, seg := range p.Segments {
		seg.FileOffset += fdelta
		seg.VirtAddr += vdelta
		for _, sect := range seg.Sections {
			sect.VirtAddr += vdelta
			for _, sym := range sect.Syms {
				sym.Addr += vdelta
			}
		}
	}
}

// diffProg returns a list of differences between p and q,
// assuming p is being checked and q is the correct answer.
func diffProg(p, q *Prog) []string {
	var errors []string
	if p.UnmappedSize != q.UnmappedSize {
		errors = append(errors, fmt.Sprintf("p.UnmappedSize = %#x, want %#x", p.UnmappedSize, q.UnmappedSize))
	}
	if p.HeaderSize != q.HeaderSize {
		errors = append(errors, fmt.Sprintf("p.HeaderSize = %#x, want %#x", p.HeaderSize, q.HeaderSize))
	}
	if p.Entry != q.Entry {
		errors = append(errors, fmt.Sprintf("p.Entry = %#x, want %#x", p.Entry, q.Entry))
	}
	for i := 0; i < len(p.Segments) || i < len(q.Segments); i++ {
		if i >= len(p.Segments) {
			errors = append(errors, fmt.Sprintf("p missing segment %q", q.Segments[i].Name))
			continue
		}
		if i >= len(q.Segments) {
			errors = append(errors, fmt.Sprintf("p has extra segment %q", p.Segments[i].Name))
			continue
		}
		pseg := p.Segments[i]
		qseg := q.Segments[i]
		if pseg.Name != qseg.Name {
			errors = append(errors, fmt.Sprintf("segment %d Name = %q, want %q", i, pseg.Name, qseg.Name))
			continue // probably out of sync
		}
		if pseg.VirtAddr != qseg.VirtAddr {
			errors = append(errors, fmt.Sprintf("segment %q VirtAddr = %#x, want %#x", pseg.Name, pseg.VirtAddr, qseg.VirtAddr))
		}
		if pseg.VirtSize != qseg.VirtSize {
			errors = append(errors, fmt.Sprintf("segment %q VirtSize = %#x, want %#x", pseg.Name, pseg.VirtSize, qseg.VirtSize))
		}
		if pseg.FileOffset != qseg.FileOffset {
			errors = append(errors, fmt.Sprintf("segment %q FileOffset = %#x, want %#x", pseg.Name, pseg.FileOffset, qseg.FileOffset))
		}
		if pseg.FileSize != qseg.FileSize {
			errors = append(errors, fmt.Sprintf("segment %q FileSize = %#x, want %#x", pseg.Name, pseg.FileSize, qseg.FileSize))
		}
		if len(pseg.Data) != len(qseg.Data) {
			errors = append(errors, fmt.Sprintf("segment %q len(Data) = %d, want %d", pseg.Name, len(pseg.Data), len(qseg.Data)))
		} else if !bytes.Equal(pseg.Data, qseg.Data) {
			errors = append(errors, fmt.Sprintf("segment %q Data mismatch:\n\thave %x\n\twant %x", pseg.Name, pseg.Data, qseg.Data))
		}

		for j := 0; j < len(pseg.Sections) || j < len(qseg.Sections); j++ {
			if j >= len(pseg.Sections) {
				errors = append(errors, fmt.Sprintf("segment %q missing section %q", qseg.Sections[i].Name))
				continue
			}
			if j >= len(qseg.Sections) {
				errors = append(errors, fmt.Sprintf("segment %q has extra section %q", pseg.Sections[i].Name))
				continue
			}
			psect := pseg.Sections[j]
			qsect := qseg.Sections[j]
			if psect.Name != qsect.Name {
				errors = append(errors, fmt.Sprintf("segment %q, section %d Name = %q, want %q", pseg.Name, j, psect.Name, qsect.Name))
				continue // probably out of sync
			}

			if psect.VirtAddr != qsect.VirtAddr {
				errors = append(errors, fmt.Sprintf("segment %q section %q VirtAddr = %#x, want %#x", pseg.Name, psect.Name, psect.VirtAddr, qsect.VirtAddr))
			}
			if psect.Size != qsect.Size {
				errors = append(errors, fmt.Sprintf("segment %q section %q Size = %#x, want %#x", pseg.Name, psect.Name, psect.Size, qsect.Size))
			}
			if psect.Align != qsect.Align {
				errors = append(errors, fmt.Sprintf("segment %q section %q Align = %#x, want %#x", pseg.Name, psect.Name, psect.Align, qsect.Align))
			}
		}
	}

	return errors
}

// cloneProg returns a deep copy of p.
func cloneProg(p *Prog) *Prog {
	q := new(Prog)
	*q = *p
	q.Segments = make([]*Segment, len(p.Segments))
	for i, seg := range p.Segments {
		q.Segments[i] = cloneSegment(seg)
	}
	return q
}

// cloneSegment returns a deep copy of seg.
func cloneSegment(seg *Segment) *Segment {
	t := new(Segment)
	*t = *seg
	t.Sections = make([]*Section, len(seg.Sections))
	for i, sect := range seg.Sections {
		t.Sections[i] = cloneSection(sect)
	}
	t.Data = make([]byte, len(seg.Data))
	copy(t.Data, seg.Data)
	return t
}

// cloneSection returns a deep copy of section.
func cloneSection(sect *Section) *Section {
	// At the moment, there's nothing we need to make a deep copy of.
	t := new(Section)
	*t = *sect
	return t
}

const saveMismatch = true

// checkGolden checks that data matches the named file.
// If not, it reports the error to the test.
func checkGolden(t *testing.T, data []byte, name string) {
	golden := mustParseHexdumpFile(t, name)
	if !bytes.Equal(data, golden) {
		if saveMismatch {
			ioutil.WriteFile(name+".raw", data, 0666)
			ioutil.WriteFile(name+".hex", []byte(hexdump(data)), 0666)
		}
		// TODO(rsc): A better diff would be nice, as needed.
		i := 0
		for i < len(data) && i < len(golden) && data[i] == golden[i] {
			i++
		}
		if i >= len(data) {
			t.Errorf("%s: output file shorter than expected: have %d bytes, want %d", name, len(data), len(golden))
		} else if i >= len(golden) {
			t.Errorf("%s: output file larger than expected: have %d bytes, want %d", name, len(data), len(golden))
		} else {
			t.Errorf("%s: output file differs at byte %d: have %#02x, want %#02x", name, i, data[i], golden[i])
		}
	}
}
