// Copyright 2022 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 completion

import (
	"fmt"
	"go/ast"
	"go/types"
	"strings"

	"golang.org/x/tools/gopls/internal/protocol"
)

// golang/go#51089
// *testing.F deserves special treatment as member use is constrained:
// The arguments to f.Fuzz are determined by the arguments to a previous f.Add
// Inside f.Fuzz only f.Failed and f.Name are allowed.
// PJW: are there other packages where we can deduce usage constraints?

// if we find fuzz completions, then return true, as those are the only completions to offer
func (c *completer) fuzz(testingF types.Type, imp *importInfo, cb func(candidate)) bool {
	// 1. inside f.Fuzz? (only f.Failed and f.Name)
	// 2. possible completing f.Fuzz?
	//    [Ident,SelectorExpr,Callexpr,ExprStmt,BlockiStmt,FuncDecl(Fuzz...)]
	// 3. before f.Fuzz, same (for 2., offer choice when looking at an F)

	mset := types.NewMethodSet(testingF)

	// does the path contain FuncLit as arg to f.Fuzz CallExpr?
	inside := false
Loop:
	for i, n := range c.path {
		switch v := n.(type) {
		case *ast.CallExpr:
			if len(v.Args) != 1 {
				continue Loop
			}
			if _, ok := v.Args[0].(*ast.FuncLit); !ok {
				continue
			}
			if s, ok := v.Fun.(*ast.SelectorExpr); !ok || s.Sel.Name != "Fuzz" {
				continue
			}
			if i > 2 { // avoid t.Fuzz itself in tests
				inside = true
				break Loop
			}
		}
	}
	if inside {
		for i := range mset.Len() {
			o := mset.At(i).Obj()
			if o.Name() == "Failed" || o.Name() == "Name" {
				cb(candidate{
					obj:         o,
					score:       stdScore,
					imp:         imp,
					addressable: true,
				})
			}
		}
		return true
	}
	// if it could be t.Fuzz, look for the preceding t.Add
	id, ok := c.path[0].(*ast.Ident)
	if ok && strings.HasPrefix("Fuzz", id.Name) {
		var add *ast.CallExpr
		f := func(n ast.Node) bool {
			if n == nil {
				return true
			}
			call, ok := n.(*ast.CallExpr)
			if !ok {
				return true
			}
			s, ok := call.Fun.(*ast.SelectorExpr)
			if !ok {
				return true
			}
			if s.Sel.Name != "Add" {
				return true
			}
			// Sel.X should be of type *testing.F
			got := c.pkg.TypesInfo().Types[s.X]
			if got.Type.String() == "*testing.F" {
				add = call
			}
			return false // because we're done...
		}
		// look at the enclosing FuzzFoo functions
		if len(c.path) < 2 {
			return false
		}
		n := c.path[len(c.path)-2]
		if _, ok := n.(*ast.FuncDecl); !ok {
			// the path should start with ast.File, ast.FuncDecl, ...
			// but it didn't, so give up
			return false
		}
		ast.Inspect(n, f)
		if add == nil {
			// looks like f.Fuzz without a preceding f.Add.
			// let the regular completion handle it.
			return false
		}

		lbl := "Fuzz(func(t *testing.T"
		for i, a := range add.Args {
			info := c.pkg.TypesInfo().TypeOf(a)
			if info == nil {
				return false // How could this happen, but better safe than panic.
			}
			lbl += fmt.Sprintf(", %c %s", 'a'+i, info)
		}
		lbl += ")"
		xx := CompletionItem{
			Label:         lbl,
			InsertText:    lbl,
			Kind:          protocol.FunctionCompletion,
			Depth:         0,
			Score:         10, // pretty confident the user should see this
			Documentation: "argument types from f.Add",
			isSlice:       false,
		}
		c.items = append(c.items, xx)
		for i := range mset.Len() {
			o := mset.At(i).Obj()
			if o.Name() != "Fuzz" {
				cb(candidate{
					obj:         o,
					score:       stdScore,
					imp:         imp,
					addressable: true,
				})
			}
		}
		return true // done
	}
	// let the standard processing take care of it instead
	return false
}
