// Copyright 2015 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 tests

import (
	_ "embed"
	"go/ast"
	"go/token"
	"go/types"
	"regexp"
	"strings"
	"unicode"
	"unicode/utf8"

	"golang.org/x/tools/go/analysis"
	"golang.org/x/tools/internal/analysisinternal/analyzerutil"
	"golang.org/x/tools/internal/astutil"
	"golang.org/x/tools/internal/typesinternal"
)

//go:embed doc.go
var doc string

var Analyzer = &analysis.Analyzer{
	Name: "tests",
	Doc:  analyzerutil.MustExtractDoc(doc, "tests"),
	URL:  "https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/tests",
	Run:  run,
}

var acceptedFuzzTypes = []types.Type{
	types.Typ[types.String],
	types.Typ[types.Bool],
	types.Typ[types.Float32],
	types.Typ[types.Float64],
	types.Typ[types.Int],
	types.Typ[types.Int8],
	types.Typ[types.Int16],
	types.Typ[types.Int32],
	types.Typ[types.Int64],
	types.Typ[types.Uint],
	types.Typ[types.Uint8],
	types.Typ[types.Uint16],
	types.Typ[types.Uint32],
	types.Typ[types.Uint64],
	types.NewSlice(types.Universe.Lookup("byte").Type()),
}

func run(pass *analysis.Pass) (any, error) {
	for _, f := range pass.Files {
		if !strings.HasSuffix(pass.Fset.File(f.FileStart).Name(), "_test.go") {
			continue
		}
		for _, decl := range f.Decls {
			fn, ok := decl.(*ast.FuncDecl)
			if !ok || fn.Recv != nil {
				// Ignore non-functions or functions with receivers.
				continue
			}
			switch {
			case strings.HasPrefix(fn.Name.Name, "Example"):
				checkExampleName(pass, fn)
				checkExampleOutput(pass, fn, f.Comments)
			case strings.HasPrefix(fn.Name.Name, "Test"):
				checkTest(pass, fn, "Test")
			case strings.HasPrefix(fn.Name.Name, "Benchmark"):
				checkTest(pass, fn, "Benchmark")
			case strings.HasPrefix(fn.Name.Name, "Fuzz"):
				checkTest(pass, fn, "Fuzz")
				checkFuzz(pass, fn)
			}
		}
	}
	return nil, nil
}

// checkFuzz checks the contents of a fuzz function.
func checkFuzz(pass *analysis.Pass, fn *ast.FuncDecl) {
	params := checkFuzzCall(pass, fn)
	if params != nil {
		checkAddCalls(pass, fn, params)
	}
}

// checkFuzzCall checks the arguments of f.Fuzz() calls:
//
//  1. f.Fuzz() should call a function and it should be of type (*testing.F).Fuzz().
//  2. The called function in f.Fuzz(func(){}) should not return result.
//  3. First argument of func() should be of type *testing.T
//  4. Second argument onwards should be of type []byte, string, bool, byte,
//     rune, float32, float64, int, int8, int16, int32, int64, uint, uint8, uint16,
//     uint32, uint64
//  5. func() must not call any *F methods, e.g. (*F).Log, (*F).Error, (*F).Skip
//     The only *F methods that are allowed in the (*F).Fuzz function are (*F).Failed and (*F).Name.
//
// Returns the list of parameters to the fuzz function, if they are valid fuzz parameters.
func checkFuzzCall(pass *analysis.Pass, fn *ast.FuncDecl) (params *types.Tuple) {
	ast.Inspect(fn, func(n ast.Node) bool {
		call, ok := n.(*ast.CallExpr)
		if ok {
			if !isFuzzTargetDotFuzz(pass, call) {
				return true
			}

			// Only one argument (func) must be passed to (*testing.F).Fuzz.
			if len(call.Args) != 1 {
				return true
			}
			expr := call.Args[0]
			if pass.TypesInfo.Types[expr].Type == nil {
				return true
			}
			t := pass.TypesInfo.Types[expr].Type.Underlying()
			tSign, argOk := t.(*types.Signature)
			// Argument should be a function
			if !argOk {
				pass.ReportRangef(expr, "argument to Fuzz must be a function")
				return false
			}
			// ff Argument function should not return
			if tSign.Results().Len() != 0 {
				pass.ReportRangef(expr, "fuzz target must not return any value")
			}
			// ff Argument function should have 1 or more argument
			if tSign.Params().Len() == 0 {
				pass.ReportRangef(expr, "fuzz target must have 1 or more argument")
				return false
			}
			ok := validateFuzzArgs(pass, tSign.Params(), expr)
			if ok && params == nil {
				params = tSign.Params()
			}
			// Inspect the function that was passed as an argument to make sure that
			// there are no calls to *F methods, except for Name and Failed.
			ast.Inspect(expr, func(n ast.Node) bool {
				if call, ok := n.(*ast.CallExpr); ok {
					if !isFuzzTargetDot(pass, call, "") {
						return true
					}
					if !isFuzzTargetDot(pass, call, "Name") && !isFuzzTargetDot(pass, call, "Failed") {
						pass.ReportRangef(call, "fuzz target must not call any *F methods")
					}
				}
				return true
			})
			// We do not need to look at any calls to f.Fuzz inside of a Fuzz call,
			// since they are not allowed.
			return false
		}
		return true
	})
	return params
}

// checkAddCalls checks that the arguments of f.Add calls have the same number and type of arguments as
// the signature of the function passed to (*testing.F).Fuzz
func checkAddCalls(pass *analysis.Pass, fn *ast.FuncDecl, params *types.Tuple) {
	ast.Inspect(fn, func(n ast.Node) bool {
		call, ok := n.(*ast.CallExpr)
		if ok {
			if !isFuzzTargetDotAdd(pass, call) {
				return true
			}

			// The first argument to function passed to (*testing.F).Fuzz is (*testing.T).
			if len(call.Args) != params.Len()-1 {
				pass.ReportRangef(call, "wrong number of values in call to (*testing.F).Add: %d, fuzz target expects %d", len(call.Args), params.Len()-1)
				return true
			}
			var mismatched []int
			for i, expr := range call.Args {
				if pass.TypesInfo.Types[expr].Type == nil {
					return true
				}
				t := pass.TypesInfo.Types[expr].Type
				if !types.Identical(t, params.At(i+1).Type()) {
					mismatched = append(mismatched, i)
				}
			}
			// If just one of the types is mismatched report for that
			// type only. Otherwise report for the whole call to (*testing.F).Add
			if len(mismatched) == 1 {
				i := mismatched[0]
				expr := call.Args[i]
				t := pass.TypesInfo.Types[expr].Type
				pass.ReportRangef(expr, "mismatched type in call to (*testing.F).Add: %v, fuzz target expects %v", t, params.At(i+1).Type())
			} else if len(mismatched) > 1 {
				var gotArgs, wantArgs []types.Type
				for i := 0; i < len(call.Args); i++ {
					gotArgs, wantArgs = append(gotArgs, pass.TypesInfo.Types[call.Args[i]].Type), append(wantArgs, params.At(i+1).Type())
				}
				pass.ReportRangef(call, "mismatched types in call to (*testing.F).Add: %v, fuzz target expects %v", gotArgs, wantArgs)
			}
		}
		return true
	})
}

// isFuzzTargetDotFuzz reports whether call is (*testing.F).Fuzz().
func isFuzzTargetDotFuzz(pass *analysis.Pass, call *ast.CallExpr) bool {
	return isFuzzTargetDot(pass, call, "Fuzz")
}

// isFuzzTargetDotAdd reports whether call is (*testing.F).Add().
func isFuzzTargetDotAdd(pass *analysis.Pass, call *ast.CallExpr) bool {
	return isFuzzTargetDot(pass, call, "Add")
}

// isFuzzTargetDot reports whether call is (*testing.F).<name>().
func isFuzzTargetDot(pass *analysis.Pass, call *ast.CallExpr, name string) bool {
	if selExpr, ok := call.Fun.(*ast.SelectorExpr); ok {
		if !isTestingType(pass.TypesInfo.Types[selExpr.X].Type, "F") {
			return false
		}
		if name == "" || selExpr.Sel.Name == name {
			return true
		}
	}
	return false
}

// Validate the arguments of fuzz target.
func validateFuzzArgs(pass *analysis.Pass, params *types.Tuple, expr ast.Expr) bool {
	fLit, isFuncLit := expr.(*ast.FuncLit)
	exprRange := expr
	ok := true
	if !isTestingType(params.At(0).Type(), "T") {
		if isFuncLit {
			exprRange = fLit.Type.Params.List[0].Type
		}
		pass.ReportRangef(exprRange, "the first parameter of a fuzz target must be *testing.T")
		ok = false
	}
	for i := 1; i < params.Len(); i++ {
		if !isAcceptedFuzzType(params.At(i).Type()) {
			if isFuncLit {
				curr := 0
				for _, field := range fLit.Type.Params.List {
					curr += len(field.Names)
					if i < curr {
						exprRange = field.Type
						break
					}
				}
			}
			pass.ReportRangef(exprRange, "fuzzing arguments can only have the following types: %s", formatAcceptedFuzzType())
			ok = false
		}
	}
	return ok
}

func isTestingType(typ types.Type, testingType string) bool {
	// No Unalias here: I doubt "go test" recognizes
	// "type A = *testing.T; func Test(A) {}" as a test.
	ptr, ok := typ.(*types.Pointer)
	if !ok {
		return false
	}
	return typesinternal.IsTypeNamed(ptr.Elem(), "testing", testingType)
}

// Validate that fuzz target function's arguments are of accepted types.
func isAcceptedFuzzType(paramType types.Type) bool {
	for _, typ := range acceptedFuzzTypes {
		if types.Identical(typ, paramType) {
			return true
		}
	}
	return false
}

func formatAcceptedFuzzType() string {
	var acceptedFuzzTypesStrings []string
	for _, typ := range acceptedFuzzTypes {
		acceptedFuzzTypesStrings = append(acceptedFuzzTypesStrings, typ.String())
	}
	acceptedFuzzTypesMsg := strings.Join(acceptedFuzzTypesStrings, ", ")
	return acceptedFuzzTypesMsg
}

func isExampleSuffix(s string) bool {
	r, size := utf8.DecodeRuneInString(s)
	return size > 0 && unicode.IsLower(r)
}

func isTestSuffix(name string) bool {
	if len(name) == 0 {
		// "Test" is ok.
		return true
	}
	r, _ := utf8.DecodeRuneInString(name)
	return !unicode.IsLower(r)
}

func isTestParam(typ ast.Expr, wantType string) bool {
	ptr, ok := typ.(*ast.StarExpr)
	if !ok {
		// Not a pointer.
		return false
	}
	// No easy way of making sure it's a *testing.T or *testing.B:
	// ensure the name of the type matches.
	if name, ok := ptr.X.(*ast.Ident); ok {
		return name.Name == wantType
	}
	if sel, ok := ptr.X.(*ast.SelectorExpr); ok {
		return sel.Sel.Name == wantType
	}
	return false
}

func lookup(pkg *types.Package, name string) []types.Object {
	if o := pkg.Scope().Lookup(name); o != nil {
		return []types.Object{o}
	}

	var ret []types.Object
	// Search through the imports to see if any of them define name.
	// It's hard to tell in general which package is being tested, so
	// for the purposes of the analysis, allow the object to appear
	// in any of the imports. This guarantees there are no false positives
	// because the example needs to use the object so it must be defined
	// in the package or one if its imports. On the other hand, false
	// negatives are possible, but should be rare.
	for _, imp := range pkg.Imports() {
		if obj := imp.Scope().Lookup(name); obj != nil {
			ret = append(ret, obj)
		}
	}
	return ret
}

// This pattern is taken from /go/src/go/doc/example.go
var outputRe = regexp.MustCompile(`(?i)^[[:space:]]*(unordered )?output:`)

type commentMetadata struct {
	isOutput bool
	pos      token.Pos
}

func checkExampleOutput(pass *analysis.Pass, fn *ast.FuncDecl, fileComments []*ast.CommentGroup) {
	commentsInExample := []commentMetadata{}
	numOutputs := 0

	// Find the comment blocks that are in the example. These comments are
	// guaranteed to be in order of appearance.
	for _, cg := range fileComments {
		if cg.Pos() < fn.Pos() {
			continue
		} else if cg.End() > fn.End() {
			break
		}

		isOutput := outputRe.MatchString(cg.Text())
		if isOutput {
			numOutputs++
		}

		commentsInExample = append(commentsInExample, commentMetadata{
			isOutput: isOutput,
			pos:      cg.Pos(),
		})
	}

	// Change message based on whether there are multiple output comment blocks.
	msg := "output comment block must be the last comment block"
	if numOutputs > 1 {
		msg = "there can only be one output comment block per example"
	}

	for i, cg := range commentsInExample {
		// Check for output comments that are not the last comment in the example.
		isLast := (i == len(commentsInExample)-1)
		if cg.isOutput && !isLast {
			pass.Report(
				analysis.Diagnostic{
					Pos:     cg.pos,
					Message: msg,
				},
			)
		}
	}
}

func checkExampleName(pass *analysis.Pass, fn *ast.FuncDecl) {
	fnName := fn.Name.Name
	if params := fn.Type.Params; len(params.List) != 0 {
		pass.Reportf(fn.Pos(), "%s should be niladic", fnName)
	}
	if results := fn.Type.Results; results != nil && len(results.List) != 0 {
		pass.Reportf(fn.Pos(), "%s should return nothing", fnName)
	}
	if tparams := fn.Type.TypeParams; tparams != nil && len(tparams.List) > 0 {
		pass.Reportf(fn.Pos(), "%s should not have type params", fnName)
	}

	if fnName == "Example" {
		// Nothing more to do.
		return
	}

	var (
		exName = strings.TrimPrefix(fnName, "Example")
		elems  = strings.SplitN(exName, "_", 3)
		ident  = elems[0]
		objs   = lookup(pass.Pkg, ident)
	)
	if ident != "" && len(objs) == 0 {
		// Check ExampleFoo and ExampleBadFoo.
		pass.Reportf(fn.Pos(), "%s refers to unknown identifier: %s", fnName, ident)
		// Abort since obj is absent and no subsequent checks can be performed.
		return
	}
	if len(elems) < 2 {
		// Nothing more to do.
		return
	}

	if ident == "" {
		// Check Example_suffix and Example_BadSuffix.
		if residual := strings.TrimPrefix(exName, "_"); !isExampleSuffix(residual) {
			pass.Reportf(fn.Pos(), "%s has malformed example suffix: %s", fnName, residual)
		}
		return
	}

	mmbr := elems[1]
	if !isExampleSuffix(mmbr) {
		// Check ExampleFoo_Method and ExampleFoo_BadMethod.
		found := false
		// Check if Foo.Method exists in this package or its imports.
		for _, obj := range objs {
			if obj, _, _ := types.LookupFieldOrMethod(obj.Type(), true, obj.Pkg(), mmbr); obj != nil {
				found = true
				break
			}
		}
		if !found {
			pass.Reportf(fn.Pos(), "%s refers to unknown field or method: %s.%s", fnName, ident, mmbr)
		}
	}
	if len(elems) == 3 && !isExampleSuffix(elems[2]) {
		// Check ExampleFoo_Method_suffix and ExampleFoo_Method_Badsuffix.
		pass.Reportf(fn.Pos(), "%s has malformed example suffix: %s", fnName, elems[2])
	}
}

func checkTest(pass *analysis.Pass, fn *ast.FuncDecl, prefix string) {
	// Want functions with 0 results and 1 parameter.
	if fn.Type.Results != nil && len(fn.Type.Results.List) > 0 ||
		fn.Type.Params == nil ||
		len(fn.Type.Params.List) != 1 ||
		len(fn.Type.Params.List[0].Names) > 1 {
		return
	}

	// The param must look like a *testing.T or *testing.B.
	if !isTestParam(fn.Type.Params.List[0].Type, prefix[:1]) {
		return
	}

	if tparams := fn.Type.TypeParams; tparams != nil && len(tparams.List) > 0 {
		// Note: cmd/go/internal/load also errors about TestXXX and BenchmarkXXX functions with type parameters.
		// We have currently decided to also warn before compilation/package loading. This can help users in IDEs.
		pass.ReportRangef(astutil.RangeOf(tparams.Opening, tparams.Closing),
			"%s has type parameters: it will not be run by go test as a %sXXX function",
			fn.Name.Name, prefix)
	}

	if !isTestSuffix(fn.Name.Name[len(prefix):]) {
		pass.ReportRangef(fn.Name, "%s has malformed name: first letter after '%s' must not be lowercase", fn.Name.Name, prefix)
	}
}
