// Copyright 2018 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 objectpath_test

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/importer"
	"go/parser"
	"go/token"
	"go/types"
	"strings"
	"testing"

	"golang.org/x/tools/go/buildutil"
	"golang.org/x/tools/go/gcexportdata"
	"golang.org/x/tools/go/loader"
	"golang.org/x/tools/go/types/objectpath"
)

func TestPaths(t *testing.T) {
	pkgs := map[string]map[string]string{
		"b": {"b.go": `
package b

import "a"

const C = a.Int(0)

func F(a, b, c int, d a.T)

type T struct{ A int; b int; a.T }

func (T) M() *interface{ f() }

type U T

type A = struct{ x int }

var V []*a.T

type M map[struct{x int}]struct{y int}

func unexportedFunc()
type unexportedType struct{}

type S struct{t struct{x int}}
type R []struct{y int}
type Q [2]struct{z int}
`},
		"a": {"a.go": `
package a

type Int int

type T struct{x, y int}

`},
	}
	paths := []pathTest{
		// Good paths
		{"b", "C", "const b.C a.Int", ""},
		{"b", "F", "func b.F(a int, b int, c int, d a.T)", ""},
		{"b", "F.PA0", "var a int", ""},
		{"b", "F.PA1", "var b int", ""},
		{"b", "F.PA2", "var c int", ""},
		{"b", "F.PA3", "var d a.T", ""},
		{"b", "T", "type b.T struct{A int; b int; a.T}", ""},
		{"b", "T.O", "type b.T struct{A int; b int; a.T}", ""},
		{"b", "T.UF0", "field A int", ""},
		{"b", "T.UF1", "field b int", ""},
		{"b", "T.UF2", "field T a.T", ""},
		{"b", "U.UF2", "field T a.T", ""}, // U.U... are aliases for T.U...
		{"b", "A", "type b.A = struct{x int}", ""},
		{"b", "A.F0", "field x int", ""},
		{"b", "V", "var b.V []*a.T", ""},
		{"b", "M", "type b.M map[struct{x int}]struct{y int}", ""},
		{"b", "M.UKF0", "field x int", ""},
		{"b", "M.UEF0", "field y int", ""},
		{"b", "T.M0", "func (b.T).M() *interface{f()}", ""}, // concrete method
		{"b", "T.M0.RA0", "var  *interface{f()}", ""},       // parameter
		{"b", "T.M0.RA0.EM0", "func (interface).f()", ""},   // interface method
		{"b", "unexportedType", "type b.unexportedType struct{}", ""},
		{"b", "S.UF0.F0", "field x int", ""},
		{"b", "R.UEF0", "field y int", ""},
		{"b", "Q.UEF0", "field z int", ""},
		{"a", "T", "type a.T struct{x int; y int}", ""},
		{"a", "T.UF0", "field x int", ""},

		// Bad paths
		{"b", "", "", "empty path"},
		{"b", "missing", "", `package b does not contain "missing"`},
		{"b", "F.U", "", "invalid path: ends with 'U', want [AFMO]"},
		{"b", "F.PA3.O", "", "path denotes type a.T struct{x int; y int}, which belongs to a different package"},
		{"b", "F.PA!", "", `invalid path: bad numeric operand "" for code 'A'`},
		{"b", "F.PA3.UF0", "", "path denotes field x int, which belongs to a different package"},
		{"b", "F.PA3.UF5", "", "field index 5 out of range [0-2)"},
		{"b", "V.EE", "", "invalid path: ends with 'E', want [AFMO]"},
		{"b", "F..O", "", "invalid path: unexpected '.' in type context"},
		{"b", "T.OO", "", "invalid path: code 'O' in object context"},
		{"b", "T.EO", "", "cannot apply 'E' to b.T (got *types.Named, want pointer, slice, array, chan or map)"},
		{"b", "A.O", "", "cannot apply 'O' to struct{x int} (got *types.Struct, want named or type param)"},
		{"b", "A.UF0", "", "cannot apply 'U' to struct{x int} (got *types.Struct, want named)"},
		{"b", "M.UPO", "", "cannot apply 'P' to map[struct{x int}]struct{y int} (got *types.Map, want signature)"},
		{"b", "C.O", "", "path denotes type a.Int int, which belongs to a different package"},
		{"b", "T.M9", "", "method index 9 out of range [0-1)"},
		{"b", "M.UF0", "", "cannot apply 'F' to map[struct{x int}]struct{y int} (got *types.Map, want struct)"},
		{"b", "V.KO", "", "cannot apply 'K' to []*a.T (got *types.Slice, want map)"},
		{"b", "V.A4", "", "cannot apply 'A' to []*a.T (got *types.Slice, want tuple)"},
		{"b", "V.RA0", "", "cannot apply 'R' to []*a.T (got *types.Slice, want signature)"},
		{"b", "F.PA4", "", "tuple index 4 out of range [0-4)"},
		{"b", "F.XO", "", "invalid path: unknown code 'X'"},
	}
	conf := loader.Config{Build: buildutil.FakeContext(pkgs)}
	conf.Import("a")
	conf.Import("b")
	prog, err := conf.Load()
	if err != nil {
		t.Fatal(err)
	}

	for _, test := range paths {
		if err := testPath(prog, test); err != nil {
			t.Error(err)
		}
	}

	// bad objects
	bInfo := prog.Imported["b"]
	for _, test := range []struct {
		obj     types.Object
		wantErr string
	}{
		{types.Universe.Lookup("nil"), "predeclared nil has no path"},
		{types.Universe.Lookup("len"), "predeclared builtin len has no path"},
		{types.Universe.Lookup("int"), "predeclared type int has no path"},
		{bInfo.Implicits[bInfo.Files[0].Imports[0]], "no path for package a"}, // import "a"
		{bInfo.Pkg.Scope().Lookup("unexportedFunc"), "no path for non-exported func b.unexportedFunc()"},
	} {
		path, err := objectpath.For(test.obj)
		if err == nil {
			t.Errorf("Object(%s) = %q, want error", test.obj, path)
			continue
		}
		if err.Error() != test.wantErr {
			t.Errorf("Object(%s) error was %q, want %q", test.obj, err, test.wantErr)
			continue
		}
	}
}

type pathTest struct {
	pkg     string
	path    objectpath.Path
	wantobj string
	wantErr string
}

func testPath(prog *loader.Program, test pathTest) error {
	// We test objectpath by enumerating a set of paths
	// and ensuring that Path(pkg, Object(pkg, path)) == path.
	//
	// It might seem more natural to invert the test:
	// identify a set of objects and for each one,
	// ensure that Object(pkg, Path(pkg, obj)) == obj.
	// However, for most interesting test cases there is no
	// easy way to identify the object short of applying
	// a series of destructuring operations to pkg---which
	// is essentially what objectpath.Object does.
	// (We do a little of that when testing bad paths, below.)
	//
	// The downside is that the test depends on the path encoding.
	// The upside is that the test exercises the encoding.

	pkg := prog.Imported[test.pkg].Pkg
	// check path -> object
	obj, err := objectpath.Object(pkg, test.path)
	if (test.wantErr != "") != (err != nil) {
		return fmt.Errorf("Object(%s, %q) returned error %q, want %q", pkg.Path(), test.path, err, test.wantErr)
	}
	if test.wantErr != "" {
		if got := stripSubscripts(err.Error()); got != test.wantErr {
			return fmt.Errorf("Object(%s, %q) error was %q, want %q",
				pkg.Path(), test.path, got, test.wantErr)
		}
		return nil
	}
	// Inv: err == nil

	if objString := stripSubscripts(obj.String()); objString != test.wantobj {
		return fmt.Errorf("Object(%s, %q) = %s, want %s", pkg.Path(), test.path, objString, test.wantobj)
	}
	if obj.Pkg() != pkg {
		return fmt.Errorf("Object(%s, %q) = %v, which belongs to package %s",
			pkg.Path(), test.path, obj, obj.Pkg().Path())
	}

	// check object -> path
	path2, err := objectpath.For(obj)
	if err != nil {
		return fmt.Errorf("For(%v) failed: %v, want %q", obj, err, test.path)
	}
	// We do not require that test.path == path2. Aliases are legal.
	// But we do require that Object(path2) finds the same object.
	obj2, err := objectpath.Object(pkg, path2)
	if err != nil {
		return fmt.Errorf("Object(%s, %q) failed: %v (roundtrip from %q)", pkg.Path(), path2, err, test.path)
	}
	if obj2 != obj {
		return fmt.Errorf("Object(%s, For(obj)) != obj: got %s, obj is %s (path1=%q, path2=%q)", pkg.Path(), obj2, obj, test.path, path2)
	}
	return nil
}

// stripSubscripts removes type parameter id subscripts.
//
// TODO(rfindley): remove this function once subscripts are removed from the
// type parameter type string.
func stripSubscripts(s string) string {
	var runes []rune
	for _, r := range s {
		// For debugging/uniqueness purposes, TypeString on a type parameter adds a
		// subscript corresponding to the type parameter's unique id. This is going
		// to be removed, but in the meantime we skip the subscript runes to get a
		// deterministic output.
		if '₀' <= r && r < '₀'+10 {
			continue // trim type parameter subscripts
		}
		runes = append(runes, r)
	}
	return string(runes)
}

// TestSourceAndExportData uses objectpath to compute a correspondence
// of objects between two versions of the same package, one loaded from
// source, the other from export data.
func TestSourceAndExportData(t *testing.T) {
	const src = `
package p

type I int

func (I) F() *struct{ X, Y int } {
	return nil
}

type Foo interface {
	Method() (string, func(int) struct{ X int })
}

var X chan struct{ Z int }
var Z map[string]struct{ A int }
`

	// Parse source file and type-check it as a package, "src".
	fset := token.NewFileSet()
	f, err := parser.ParseFile(fset, "src.go", src, 0)
	if err != nil {
		t.Fatal(err)
	}
	conf := types.Config{Importer: importer.For("source", nil)}
	info := &types.Info{
		Defs: make(map[*ast.Ident]types.Object),
	}
	srcpkg, err := conf.Check("src/p", fset, []*ast.File{f}, info)
	if err != nil {
		t.Fatal(err)
	}

	// Export binary export data then reload it as a new package, "bin".
	var buf bytes.Buffer
	if err := gcexportdata.Write(&buf, fset, srcpkg); err != nil {
		t.Fatal(err)
	}

	imports := make(map[string]*types.Package)
	binpkg, err := gcexportdata.Read(&buf, fset, imports, "bin/p")
	if err != nil {
		t.Fatal(err)
	}

	// Now find the correspondences between them.
	for _, srcobj := range info.Defs {
		if srcobj == nil {
			continue // e.g. package declaration
		}
		if _, ok := srcobj.(*types.PkgName); ok {
			continue // PkgName has no objectpath
		}

		path, err := objectpath.For(srcobj)
		if err != nil {
			t.Errorf("For(%v): %v", srcobj, err)
			continue
		}
		binobj, err := objectpath.Object(binpkg, path)
		if err != nil {
			t.Errorf("Object(%s, %q): %v", binpkg.Path(), path, err)
			continue
		}

		// Check the object strings match.
		// (We can't check that types are identical because the
		// objects belong to different type-checker realms.)
		srcstr := objectString(srcobj)
		binstr := objectString(binobj)
		if srcstr != binstr {
			t.Errorf("ObjectStrings do not match: Object(For(%q)) = %s, want %s",
				path, srcstr, binstr)
			continue
		}
	}
}

func objectString(obj types.Object) string {
	s := types.ObjectString(obj, (*types.Package).Name)

	// The printing of interface methods changed in go1.11.
	// This work-around makes the specific test pass with earlier versions.
	s = strings.Replace(s, "func (interface).Method", "func (p.Foo).Method", -1)

	return s
}

// TestOrdering uses objectpath over two Named types with the same method
// names but in a different source order and checks that objectpath is the
// same for methods with the same name.
func TestOrdering(t *testing.T) {
	pkgs := map[string]map[string]string{
		"p": {"p.go": `
package p

type T struct{ A int }

func (T) M() { }
func (T) N() { }
func (T) X() { }
func (T) Y() { }
`},
		"q": {"q.go": `
package q

type T struct{ A int }

func (T) N() { }
func (T) M() { }
func (T) Y() { }
func (T) X() { }
`}}
	conf := loader.Config{Build: buildutil.FakeContext(pkgs)}
	conf.Import("p")
	conf.Import("q")
	prog, err := conf.Load()
	if err != nil {
		t.Fatal(err)
	}
	p := prog.Imported["p"].Pkg
	q := prog.Imported["q"].Pkg

	// From here, the objectpaths generated for p and q should be the
	// same. If they are not, then we are generating an ordering that is
	// dependent on the declaration of the types within the file.
	for _, test := range []struct {
		path objectpath.Path
	}{
		{"T.M0"},
		{"T.M1"},
		{"T.M2"},
		{"T.M3"},
	} {
		pobj, err := objectpath.Object(p, test.path)
		if err != nil {
			t.Errorf("Object(%s) failed in a1: %v", test.path, err)
			continue
		}
		qobj, err := objectpath.Object(q, test.path)
		if err != nil {
			t.Errorf("Object(%s) failed in a2: %v", test.path, err)
			continue
		}
		if pobj.Name() != pobj.Name() {
			t.Errorf("Objects(%s) not equal, got a1 = %v, a2 = %v", test.path, pobj.Name(), qobj.Name())
		}
	}
}
