// 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 (
	"debug/goobj"
	"reflect"
	"strings"
	"testing"
)

// Each test case is an object file, generated from a corresponding .s file.
// The symbols in the object file with a dead_ prefix are the ones that
// should be removed from the program.
var deadTests = []string{
	"testdata/dead.6",
}

func TestDead(t *testing.T) {
	for _, obj := range deadTests {
		p := Prog{GOOS: "darwin", GOARCH: "amd64", StartSym: "start"}
		p.omitRuntime = true
		p.Error = func(s string) { t.Error(s) }
		p.init()
		p.scan(obj)
		if p.NumError > 0 {
			continue // already reported
		}
		origSyms := copyMap(p.Syms)
		origMissing := copyMap(p.Missing)
		origSymOrder := copySlice(p.SymOrder)
		origPkgSyms := copySlice(p.Packages["main"].Syms)
		p.dead()
		checkDeadMap(t, obj, "p.Syms", origSyms, p.Syms)
		checkDeadMap(t, obj, "p.Missing", origMissing, p.Missing)
		checkDeadSlice(t, obj, "p.SymOrder", origSymOrder, p.SymOrder)
		checkDeadSlice(t, obj, `p.Packages["main"].Syms`, origPkgSyms, p.Packages["main"].Syms)
	}
}

func copyMap(m interface{}) interface{} {
	v := reflect.ValueOf(m)
	out := reflect.MakeMap(v.Type())
	for _, key := range v.MapKeys() {
		out.SetMapIndex(key, v.MapIndex(key))
	}
	return out.Interface()
}

func checkDeadMap(t *testing.T, obj, name string, old, new interface{}) {
	vold := reflect.ValueOf(old)
	vnew := reflect.ValueOf(new)
	for _, vid := range vold.MapKeys() {
		id := vid.Interface().(goobj.SymID)
		if strings.HasPrefix(id.Name, "dead_") {
			if vnew.MapIndex(vid).IsValid() {
				t.Errorf("%s: %s contains unnecessary symbol %s", obj, name, id)
			}
		} else {
			if !vnew.MapIndex(vid).IsValid() {
				t.Errorf("%s: %s is missing symbol %s", obj, name, id)
			}
		}
	}
	for _, vid := range vnew.MapKeys() {
		id := vid.Interface().(goobj.SymID)
		if !vold.MapIndex(vid).IsValid() {
			t.Errorf("%s: %s contains unexpected symbol %s", obj, name, id)
		}
	}
}

func copySlice(x []*Sym) (out []*Sym) {
	return append(out, x...)
}

func checkDeadSlice(t *testing.T, obj, name string, old, new []*Sym) {
	for i, s := range old {
		if strings.HasPrefix(s.Name, "dead_") {
			continue
		}
		if len(new) == 0 {
			t.Errorf("%s: %s is missing symbol %s\nhave%v\nwant%v", obj, name, s, new, old[i:])
			return
		}
		if new[0].SymID != s.SymID {
			t.Errorf("%s: %s is incorrect: have %s, want %s\nhave%v\nwant%v", obj, name, new[0].SymID, s.SymID, new, old[i:])
			return
		}
		new = new[1:]
	}
	if len(new) > 0 {
		t.Errorf("%s: %s has unexpected symbols: %v", obj, name, new)
	}
}
