// 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 typeutil_test

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

	"golang.org/x/tools/go/types/typeutil"
	"golang.org/x/tools/internal/versions"
)

func TestStaticCallee(t *testing.T) {
	testStaticCallee(t, []string{
		`package q;
		func Abs(x int) int {
			if x < 0 {
				return -x
			}
			return x
		}`,
		`package p
		import "q"

		type T int

		func g(int)

		var f = g

		var x int

		type s struct{ f func(int) }
		func (s) g(int)

		type I interface{ f(int) }

		var a struct{b struct{c s}}

		var n map[int]func()
		var m []func()

		func calls() {
			g(x)           // a declared func
			s{}.g(x)       // a concrete method
			a.b.c.g(x)     // same
			_ = q.Abs(x)   // declared func, qualified identifier
		}

		func noncalls() {
			_ = T(x)    // a type
			f(x)        // a var
			panic(x)    // a built-in
			s{}.f(x)    // a field
			I(nil).f(x) // interface method
			m[0]()      // a map
			n[0]()      // a slice
		}
		`})
}

func TestTypeParamStaticCallee(t *testing.T) {
	testStaticCallee(t, []string{
		`package q
		func R[T any]() {}
		`,
		`package p
		import "q"
		type I interface{
			i()
		}

		type G[T any] func() T
		func F[T any]() T { var x T; return x }

		type M[T I] struct{ t T }
		func (m M[T]) noncalls() {
			m.t.i()   // method on a type parameter
		}

		func (m M[T]) calls() {
			m.calls() // method on a generic type
		}

		type Chain[T I] struct{ r struct { s M[T] } }

		type S int
		func (S) i() {}

		func Multi[TP0, TP1 any](){}

		func calls() {
			_ = F[int]()            // instantiated function
			_ = (F[int])()          // go through parens
			M[S]{}.calls()          // instantiated method
			Chain[S]{}.r.s.calls()  // same as above
			Multi[int,string]()     // multiple type parameters
			q.R[int]()              // different package
		}

		func noncalls() {
			_ = G[int](nil)()  // instantiated function
		}
		`})
}

// testStaticCallee parses and type checks each file content in contents
// as a single file package in order. Within functions that have the suffix
// "calls" it checks that the CallExprs within have a static callee.
// If the function's name == "calls" all calls must have static callees,
// and if the name != "calls", the calls must not have static callees.
// Failures are reported on t.
func testStaticCallee(t *testing.T, contents []string) {
	fset := token.NewFileSet()
	packages := make(map[string]*types.Package)
	cfg := &types.Config{Importer: closure(packages)}
	info := &types.Info{
		Instances:  make(map[*ast.Ident]types.Instance),
		Uses:       make(map[*ast.Ident]types.Object),
		Selections: make(map[*ast.SelectorExpr]*types.Selection),
	}
	versions.InitFileVersions(info)

	var files []*ast.File
	for i, content := range contents {
		// parse
		f, err := parser.ParseFile(fset, fmt.Sprintf("%d.go", i), content, 0)
		if err != nil {
			t.Fatal(err)
		}
		files = append(files, f)

		// type-check
		pkg, err := cfg.Check(f.Name.Name, fset, []*ast.File{f}, info)
		if err != nil {
			t.Fatal(err)
		}
		packages[pkg.Path()] = pkg
	}

	// check
	for _, f := range files {
		for _, decl := range f.Decls {
			if decl, ok := decl.(*ast.FuncDecl); ok && strings.HasSuffix(decl.Name.Name, "calls") {
				wantCallee := decl.Name.Name == "calls" // false within func noncalls()
				ast.Inspect(decl.Body, func(n ast.Node) bool {
					if call, ok := n.(*ast.CallExpr); ok {
						fn := typeutil.StaticCallee(info, call)
						if fn == nil && wantCallee {
							t.Errorf("%s: StaticCallee returned nil",
								fset.Position(call.Lparen))
						} else if fn != nil && !wantCallee {
							t.Errorf("%s: StaticCallee returned %s, want nil",
								fset.Position(call.Lparen), fn)
						}
					}
					return true
				})
			}
		}
	}
}
