// Copyright 2017 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 goobj

import (
	"debug/elf"
	"debug/macho"
	"debug/pe"
	"fmt"
	"internal/testenv"
	"internal/xcoff"
	"io"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
)

var (
	buildDir   string
	go1obj     string
	go2obj     string
	goarchive  string
	cgoarchive string
)

func TestMain(m *testing.M) {
	if !testenv.HasGoBuild() {
		return
	}

	if err := buildGoobj(); err != nil {
		fmt.Println(err)
		os.RemoveAll(buildDir)
		os.Exit(1)
	}

	exit := m.Run()

	os.RemoveAll(buildDir)
	os.Exit(exit)
}

func copyDir(dst, src string) error {
	err := os.MkdirAll(dst, 0777)
	if err != nil {
		return err
	}
	fis, err := ioutil.ReadDir(src)
	if err != nil {
		return err
	}
	for _, fi := range fis {
		err = copyFile(filepath.Join(dst, fi.Name()), filepath.Join(src, fi.Name()))
		if err != nil {
			return err
		}
	}
	return nil
}

func copyFile(dst, src string) (err error) {
	var s, d *os.File
	s, err = os.Open(src)
	if err != nil {
		return err
	}
	defer s.Close()
	d, err = os.Create(dst)
	if err != nil {
		return err
	}
	defer func() {
		e := d.Close()
		if err == nil {
			err = e
		}
	}()
	_, err = io.Copy(d, s)
	if err != nil {
		return err
	}
	return nil
}

func buildGoobj() error {
	var err error

	buildDir, err = ioutil.TempDir("", "TestGoobj")
	if err != nil {
		return err
	}

	go1obj = filepath.Join(buildDir, "go1.o")
	go2obj = filepath.Join(buildDir, "go2.o")
	goarchive = filepath.Join(buildDir, "go.a")

	gotool, err := testenv.GoTool()
	if err != nil {
		return err
	}

	go1src := filepath.Join("testdata", "go1.go")
	go2src := filepath.Join("testdata", "go2.go")

	out, err := exec.Command(gotool, "tool", "compile", "-o", go1obj, go1src).CombinedOutput()
	if err != nil {
		return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go1obj, go1src, err, out)
	}
	out, err = exec.Command(gotool, "tool", "compile", "-o", go2obj, go2src).CombinedOutput()
	if err != nil {
		return fmt.Errorf("go tool compile -o %s %s: %v\n%s", go2obj, go2src, err, out)
	}
	out, err = exec.Command(gotool, "tool", "pack", "c", goarchive, go1obj, go2obj).CombinedOutput()
	if err != nil {
		return fmt.Errorf("go tool pack c %s %s %s: %v\n%s", goarchive, go1obj, go2obj, err, out)
	}

	if testenv.HasCGO() {
		gopath := filepath.Join(buildDir, "gopath")
		err = copyDir(filepath.Join(gopath, "src", "mycgo"), filepath.Join("testdata", "mycgo"))
		if err == nil {
			err = ioutil.WriteFile(filepath.Join(gopath, "src", "mycgo", "go.mod"), []byte("module mycgo\n"), 0666)
		}
		if err != nil {
			return err
		}
		cmd := exec.Command(gotool, "install", "-gcflags=all="+os.Getenv("GO_GCFLAGS"), "mycgo")
		cmd.Dir = filepath.Join(gopath, "src", "mycgo")
		cmd.Env = append(os.Environ(), "GOPATH="+gopath)
		out, err = cmd.CombinedOutput()
		if err != nil {
			return fmt.Errorf("go install mycgo: %v\n%s", err, out)
		}
		pat := filepath.Join(gopath, "pkg", "*", "mycgo.a")
		ms, err := filepath.Glob(pat)
		if err != nil {
			return err
		}
		if len(ms) == 0 {
			return fmt.Errorf("cannot found paths for pattern %s", pat)
		}
		cgoarchive = ms[0]
	}

	return nil
}

// Check that a symbol has a given name, accepting both
// new and old objects.
// TODO(go115newobj): remove.
func matchSymName(symname, want string) bool {
	return symname == want ||
		strings.HasPrefix(symname, want+"#") // new style, with index
}

func TestParseGoobj(t *testing.T) {
	path := go1obj

	f, err := os.Open(path)
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()

	p, err := Parse(f, "mypkg")
	if err != nil {
		t.Fatal(err)
	}
	if p.Arch != runtime.GOARCH {
		t.Errorf("%s: got %v, want %v", path, p.Arch, runtime.GOARCH)
	}
	var found bool
	for _, s := range p.Syms {
		if matchSymName(s.Name, "mypkg.go1") {
			found = true
			break
		}
	}
	if !found {
		t.Errorf(`%s: symbol "mypkg.go1" not found`, path)
	}
}

func TestParseArchive(t *testing.T) {
	path := goarchive

	f, err := os.Open(path)
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()

	p, err := Parse(f, "mypkg")
	if err != nil {
		t.Fatal(err)
	}
	if p.Arch != runtime.GOARCH {
		t.Errorf("%s: got %v, want %v", path, p.Arch, runtime.GOARCH)
	}
	var found1 bool
	var found2 bool
	for _, s := range p.Syms {
		if matchSymName(s.Name, "mypkg.go1") {
			found1 = true
		}
		if matchSymName(s.Name, "mypkg.go2") {
			found2 = true
		}
	}
	if !found1 {
		t.Errorf(`%s: symbol "mypkg.go1" not found`, path)
	}
	if !found2 {
		t.Errorf(`%s: symbol "mypkg.go2" not found`, path)
	}
}

func TestParseCGOArchive(t *testing.T) {
	testenv.MustHaveCGO(t)

	path := cgoarchive

	f, err := os.Open(path)
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()

	p, err := Parse(f, "mycgo")
	if err != nil {
		t.Fatal(err)
	}
	if p.Arch != runtime.GOARCH {
		t.Errorf("%s: got %v, want %v", path, p.Arch, runtime.GOARCH)
	}
	var found1 bool
	var found2 bool
	for _, s := range p.Syms {
		if matchSymName(s.Name, "mycgo.go1") {
			found1 = true
		}
		if matchSymName(s.Name, "mycgo.go2") {
			found2 = true
		}
	}
	if !found1 {
		t.Errorf(`%s: symbol "mycgo.go1" not found`, path)
	}
	if !found2 {
		t.Errorf(`%s: symbol "mycgo.go2" not found`, path)
	}

	c1 := "c1"
	c2 := "c2"

	found1 = false
	found2 = false

	switch runtime.GOOS {
	case "darwin":
		c1 = "_" + c1
		c2 = "_" + c2
		for _, obj := range p.Native {
			mf, err := macho.NewFile(obj)
			if err != nil {
				t.Fatal(err)
			}
			if mf.Symtab == nil {
				continue
			}
			for _, s := range mf.Symtab.Syms {
				switch s.Name {
				case c1:
					found1 = true
				case c2:
					found2 = true
				}
			}
		}
	case "windows":
		if runtime.GOARCH == "386" {
			c1 = "_" + c1
			c2 = "_" + c2
		}
		for _, obj := range p.Native {
			pf, err := pe.NewFile(obj)
			if err != nil {
				t.Fatal(err)
			}
			for _, s := range pf.Symbols {
				switch s.Name {
				case c1:
					found1 = true
				case c2:
					found2 = true
				}
			}
		}
	case "aix":
		c1 = "." + c1
		c2 = "." + c2
		for _, obj := range p.Native {
			xf, err := xcoff.NewFile(obj)
			if err != nil {
				t.Fatal(err)
			}
			for _, s := range xf.Symbols {
				switch s.Name {
				case c1:
					found1 = true
				case c2:
					found2 = true
				}
			}
		}

	default:
		for _, obj := range p.Native {
			ef, err := elf.NewFile(obj)
			if err != nil {
				t.Fatal(err)
			}
			syms, err := ef.Symbols()
			if err != nil {
				t.Fatal(err)
			}
			for _, s := range syms {
				switch s.Name {
				case c1:
					found1 = true
				case c2:
					found2 = true
				}
			}
		}
	}

	if !found1 {
		t.Errorf(`%s: symbol %q not found`, path, c1)
	}
	if !found2 {
		t.Errorf(`%s: symbol %q not found`, path, c2)
	}
}
