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

import (
	"go/ast"
	"go/types"
	"strings"
	"unicode"
	"unicode/utf8"
)

func init() {
	register("tests",
		"check for common mistaken usages of tests/documentation examples",
		checkTestFunctions,
		funcDecl)
}

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(name string, scopes []*types.Scope) types.Object {
	for _, scope := range scopes {
		if o := scope.Lookup(name); o != nil {
			return o
		}
	}
	return nil
}

func extendedScope(f *File) []*types.Scope {
	scopes := []*types.Scope{f.pkg.typesPkg.Scope()}
	if f.basePkg != nil {
		scopes = append(scopes, f.basePkg.typesPkg.Scope())
	} else {
		// If basePkg is not specified (e.g. when checking a single file) try to
		// find it among imports.
		pkgName := f.pkg.typesPkg.Name()
		if strings.HasSuffix(pkgName, "_test") {
			basePkgName := strings.TrimSuffix(pkgName, "_test")
			for _, p := range f.pkg.typesPkg.Imports() {
				if p.Name() == basePkgName {
					scopes = append(scopes, p.Scope())
					break
				}
			}
		}
	}
	return scopes
}

func checkExample(fn *ast.FuncDecl, f *File, report reporter) {
	fnName := fn.Name.Name
	if params := fn.Type.Params; len(params.List) != 0 {
		report("%s should be niladic", fnName)
	}
	if results := fn.Type.Results; results != nil && len(results.List) != 0 {
		report("%s should return nothing", fnName)
	}

	if filesRun && !includesNonTest {
		// The coherence checks between a test and the package it tests
		// will report false positives if no non-test files have
		// been provided.
		return
	}

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

	var (
		exName = strings.TrimPrefix(fnName, "Example")
		elems  = strings.SplitN(exName, "_", 3)
		ident  = elems[0]
		obj    = lookup(ident, extendedScope(f))
	)
	if ident != "" && obj == nil {
		// Check ExampleFoo and ExampleBadFoo.
		report("%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) {
			report("%s has malformed example suffix: %s", fnName, residual)
		}
		return
	}

	mmbr := elems[1]
	if !isExampleSuffix(mmbr) {
		// Check ExampleFoo_Method and ExampleFoo_BadMethod.
		if obj, _, _ := types.LookupFieldOrMethod(obj.Type(), true, obj.Pkg(), mmbr); obj == nil {
			report("%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.
		report("%s has malformed example suffix: %s", fnName, elems[2])
	}
}

func checkTest(fn *ast.FuncDecl, prefix string, report reporter) {
	// 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 !isTestSuffix(fn.Name.Name[len(prefix):]) {
		report("%s has malformed name: first letter after '%s' must not be lowercase", fn.Name.Name, prefix)
	}
}

type reporter func(format string, args ...interface{})

// checkTestFunctions walks Test, Benchmark and Example functions checking
// malformed names, wrong signatures and examples documenting nonexistent
// identifiers.
func checkTestFunctions(f *File, node ast.Node) {
	if !strings.HasSuffix(f.name, "_test.go") {
		return
	}

	fn, ok := node.(*ast.FuncDecl)
	if !ok || fn.Recv != nil {
		// Ignore non-functions or functions with receivers.
		return
	}

	report := func(format string, args ...interface{}) { f.Badf(node.Pos(), format, args...) }

	switch {
	case strings.HasPrefix(fn.Name.Name, "Example"):
		checkExample(fn, f, report)
	case strings.HasPrefix(fn.Name.Name, "Test"):
		checkTest(fn, "Test", report)
	case strings.HasPrefix(fn.Name.Name, "Benchmark"):
		checkTest(fn, "Benchmark", report)
	}
}
