// 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 stubmethods provides the analysis logic for the quick fix
// to "Declare missing methods of TYPE" errors. (The fix logic lives
// in golang.stubMethodsFixer.)
package stubmethods

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

	"golang.org/x/tools/go/ast/edge"
	"golang.org/x/tools/go/ast/inspector"
	"golang.org/x/tools/internal/typesinternal"

	"golang.org/x/tools/gopls/internal/cache/parsego"
	"golang.org/x/tools/gopls/internal/util/bug"
	"golang.org/x/tools/gopls/internal/util/typesutil"
)

// TODO(adonovan): eliminate the confusing Fset parameter; only the
// file name and byte offset of Concrete are needed.

// IfaceStubInfo represents a concrete type
// that wants to stub out an interface type
type IfaceStubInfo struct {
	// Interface is the interface that the client wants to implement.
	// When the interface is defined, the underlying object will be a TypeName.
	// Note that we keep track of types.Object instead of types.Type in order
	// to keep a reference to the declaring object's package and the ast file
	// in the case where the concrete type file requires a new import that happens to be renamed
	// in the interface file.
	// TODO(marwan-at-work): implement interface literals.
	Fset      *token.FileSet // the FileSet used to type-check the types below
	Interface *types.TypeName
	Concrete  typesinternal.NamedOrAlias
	pointer   bool
}

// GetIfaceStubInfo determines whether the "missing method error"
// can be used to deduced what the concrete and interface types are.
//
// TODO(adonovan): this function (and its following 5 helpers) tries
// to deduce a pair of (concrete, interface) types that are related by
// an assignment, either explicitly or through a return statement or
// function call. This is essentially what the refactor/satisfy does,
// more generally. Refactor to share logic, after auditing 'satisfy'
// for safety on ill-typed code.
func GetIfaceStubInfo(fset *token.FileSet, info *types.Info, pgf *parsego.File, pos, end token.Pos) *IfaceStubInfo {
	cur, _ := pgf.Cursor.FindByPos(pos, end)
	for cur := range cur.Enclosing() {
		// TODO: do cur = unparenEnclosing(cur) first, once CL 701035 lands.
		ek, _ := cur.ParentEdge()
		switch ek {
		case edge.ValueSpec_Values:
			return fromValueSpec(fset, info, cur)
		case edge.ReturnStmt_Results:
			// An error here may not indicate a real error the user should know about, but it may.
			// Therefore, it would be best to log it out for debugging/reporting purposes instead of ignoring
			// it. However, event.Log takes a context which is not passed via the analysis package.
			// TODO(marwan-at-work): properly log this error.
			si, _ := fromReturnStmt(fset, info, cur)
			return si
		case edge.AssignStmt_Rhs:
			return fromAssignStmt(fset, info, cur)
		case edge.CallExpr_Args:
			// Note that some call expressions don't carry the interface type
			// because they don't point to a function or method declaration elsewhere.
			// For eaxmple, "var Interface = (*Concrete)(nil)". In that case, continue
			// this loop to encounter other possibilities such as *ast.ValueSpec or others.
			si := fromCallExpr(fset, info, cur)
			if si != nil {
				return si
			}
		}
	}
	return nil
}

// Emit writes to out the missing methods of si.Concrete required for it to implement si.Interface
func (si *IfaceStubInfo) Emit(out *bytes.Buffer, qual types.Qualifier) error {
	conc := si.Concrete.Obj()
	// Record all direct methods of the current object
	concreteFuncs := make(map[string]struct{})
	if named, ok := types.Unalias(si.Concrete).(*types.Named); ok {
		for method := range named.Methods() {
			concreteFuncs[method.Name()] = struct{}{}
		}
	}

	// Find subset of interface methods that the concrete type lacks.
	ifaceType := si.Interface.Type().Underlying().(*types.Interface)

	type missingFn struct {
		fn         *types.Func
		needSubtle string
	}

	var (
		missing                  []missingFn
		concreteStruct, isStruct = typesinternal.Origin(si.Concrete).Underlying().(*types.Struct)
	)

	for imethod := range ifaceType.Methods() {
		cmethod, index, _ := types.LookupFieldOrMethod(si.Concrete, si.pointer, imethod.Pkg(), imethod.Name())
		if cmethod == nil {
			missing = append(missing, missingFn{fn: imethod})
			continue
		}

		if _, ok := cmethod.(*types.Var); ok {
			// len(LookupFieldOrMethod.index) = 1 => conflict, >1 => shadow.
			return fmt.Errorf("adding method %s.%s would conflict with (or shadow) existing field",
				conc.Name(), imethod.Name())
		}

		if _, exist := concreteFuncs[imethod.Name()]; exist {
			if !types.Identical(cmethod.Type(), imethod.Type()) {
				return fmt.Errorf("method %s.%s already exists but has the wrong type: got %s, want %s",
					conc.Name(), imethod.Name(), cmethod.Type(), imethod.Type())
			}
			continue
		}

		mf := missingFn{fn: imethod}
		if isStruct && len(index) > 0 {
			field := concreteStruct.Field(index[0])

			fn := field.Name()
			if _, ok := field.Type().(*types.Pointer); ok {
				fn = "*" + fn
			}

			mf.needSubtle = fmt.Sprintf("// Subtle: this method shadows the method (%s).%s of %s.%s.\n", fn, imethod.Name(), si.Concrete.Obj().Name(), field.Name())
		}

		missing = append(missing, mf)
	}
	if len(missing) == 0 {
		return fmt.Errorf("no missing methods found")
	}

	// Format interface name (used only in a comment).
	iface := si.Interface.Name()
	if ipkg := si.Interface.Pkg(); ipkg != nil && ipkg != conc.Pkg() {
		iface = ipkg.Name() + "." + iface
	}

	// Pointer receiver?
	var star string
	if si.pointer {
		star = "*"
	}

	// If there are any that have named receiver, choose the first one.
	// Otherwise, use lowercase for the first letter of the object.
	rn := strings.ToLower(si.Concrete.Obj().Name()[0:1])
	if named, ok := types.Unalias(si.Concrete).(*types.Named); ok {
		for method := range named.Methods() {
			if recv := method.Signature().Recv(); recv.Name() != "" {
				rn = recv.Name()
				break
			}
		}
	}

	// Check for receiver name conflicts
	checkRecvName := func(tuple *types.Tuple) bool {
		for v := range tuple.Variables() {
			if rn == v.Name() {
				return true
			}
		}
		return false
	}

	for index := range missing {
		mrn := rn + " "
		sig := missing[index].fn.Signature()
		if checkRecvName(sig.Params()) || checkRecvName(sig.Results()) {
			mrn = ""
		}

		fmt.Fprintf(out, `// %s implements [%s].
%sfunc (%s%s%s%s) %s%s {
	panic("unimplemented")
}
`,
			missing[index].fn.Name(),
			iface,
			missing[index].needSubtle,
			mrn,
			star,
			si.Concrete.Obj().Name(),
			typesutil.FormatTypeParams(si.Concrete.TypeParams()),
			missing[index].fn.Name(),
			strings.TrimPrefix(types.TypeString(missing[index].fn.Type(), qual), "func"))
	}
	return nil
}

// fromCallExpr tries to find an *ast.CallExpr's function declaration and
// analyzes a function call's signature against the passed in call argument to deduce
// the concrete and interface types.
func fromCallExpr(fset *token.FileSet, info *types.Info, curCallArg inspector.Cursor) *IfaceStubInfo {

	call := curCallArg.Parent().Node().(*ast.CallExpr)
	arg := curCallArg.Node().(ast.Expr)

	concType, pointer := concreteType(arg, info)
	if concType == nil || concType.Obj().Pkg() == nil {
		return nil
	}
	tv, ok := info.Types[call.Fun]
	if !ok {
		return nil
	}
	sig, ok := types.Unalias(tv.Type).(*types.Signature)
	if !ok {
		return nil
	}

	_, argIdx := curCallArg.ParentEdge()
	var paramType types.Type
	if sig.Variadic() && argIdx >= sig.Params().Len()-1 {
		v := sig.Params().At(sig.Params().Len() - 1)
		if s, _ := v.Type().(*types.Slice); s != nil {
			paramType = s.Elem()
		}
	} else if argIdx < sig.Params().Len() {
		paramType = sig.Params().At(argIdx).Type()
	}
	if paramType == nil {
		return nil // A type error prevents us from determining the param type.
	}
	iface := ifaceObjFromType(paramType)
	if iface == nil {
		return nil
	}
	return &IfaceStubInfo{
		Fset:      fset,
		Concrete:  concType,
		pointer:   pointer,
		Interface: iface,
	}
}

// fromReturnStmt analyzes a "return" statement to extract
// a concrete type that is trying to be returned as an interface type.
//
// For example, func() io.Writer { return myType{} }
// would return StubIfaceInfo with the interface being io.Writer and the concrete type being myType{}.
func fromReturnStmt(fset *token.FileSet, info *types.Info, curResult inspector.Cursor) (*IfaceStubInfo, error) {
	concType, pointer := concreteType(curResult.Node().(ast.Expr), info)
	if concType == nil || concType.Obj().Pkg() == nil {
		return nil, nil // result is not a named or *named or alias thereof
	}
	// Inv: the return is not a spread return,
	// such as "return f()" where f() has tuple type.
	conc := concType.Obj()
	if conc.Parent() != conc.Pkg().Scope() {
		return nil, fmt.Errorf("local type %q cannot be stubbed", conc.Name())
	}

	sig := typesutil.EnclosingSignature(curResult, info)
	if sig == nil {
		// golang/go#70666: this bug may be reached in practice.
		return nil, bug.Errorf("could not find the enclosing function of the return statement")
	}
	rets := sig.Results()
	// The return operands and function results must match.
	// (Spread returns were rejected earlier.)
	ret := curResult.Parent().Node().(*ast.ReturnStmt)
	if rets.Len() != len(ret.Results) {
		return nil, fmt.Errorf("%d-operand return statement in %d-result function",
			len(ret.Results),
			rets.Len())
	}
	_, resultIdx := curResult.ParentEdge()
	iface := ifaceObjFromType(rets.At(resultIdx).Type())
	if iface == nil {
		return nil, nil
	}
	return &IfaceStubInfo{
		Fset:      fset,
		Concrete:  concType,
		pointer:   pointer,
		Interface: iface,
	}, nil
}

// fromValueSpec returns *StubIfaceInfo from a variable declaration such as
// var x io.Writer = &T{}
func fromValueSpec(fset *token.FileSet, info *types.Info, curValue inspector.Cursor) *IfaceStubInfo {

	rhs := curValue.Node().(ast.Expr)
	spec := curValue.Parent().Node().(*ast.ValueSpec)

	// Possible implicit/explicit conversion to interface type?
	ifaceNode := spec.Type // var _ myInterface = ...
	if call, ok := rhs.(*ast.CallExpr); ok && ifaceNode == nil && len(call.Args) == 1 {
		// var _ = myInterface(v)
		ifaceNode = call.Fun
		rhs = call.Args[0]
	}
	concType, pointer := concreteType(rhs, info)
	if concType == nil || concType.Obj().Pkg() == nil {
		return nil
	}
	conc := concType.Obj()
	if conc.Parent() != conc.Pkg().Scope() {
		return nil
	}

	ifaceObj := ifaceType(ifaceNode, info)
	if ifaceObj == nil {
		return nil
	}
	return &IfaceStubInfo{
		Fset:      fset,
		Concrete:  concType,
		Interface: ifaceObj,
		pointer:   pointer,
	}
}

// fromAssignStmt returns *StubIfaceInfo from a variable assignment such as
// var x io.Writer
// x = &T{}
func fromAssignStmt(fset *token.FileSet, info *types.Info, curRhs inspector.Cursor) *IfaceStubInfo {
	// The interface conversion error in an assignment is against the RHS:
	//
	//      var x io.Writer
	//      x = &T{} // error: missing method
	//          ^^^^

	assign := curRhs.Parent().Node().(*ast.AssignStmt)
	_, idx := curRhs.ParentEdge()
	lhs, rhs := assign.Lhs[idx], curRhs.Node().(ast.Expr)

	ifaceObj := ifaceType(lhs, info)
	if ifaceObj == nil {
		return nil
	}
	concType, pointer := concreteType(rhs, info)
	if concType == nil || concType.Obj().Pkg() == nil {
		return nil
	}
	conc := concType.Obj()
	if conc.Parent() != conc.Pkg().Scope() {
		return nil
	}
	return &IfaceStubInfo{
		Fset:      fset,
		Concrete:  concType,
		Interface: ifaceObj,
		pointer:   pointer,
	}
}

// ifaceType returns the named interface type to which e refers, if any.
func ifaceType(e ast.Expr, info *types.Info) *types.TypeName {
	tv, ok := info.Types[e]
	if !ok {
		return nil
	}
	return ifaceObjFromType(tv.Type)
}

func ifaceObjFromType(t types.Type) *types.TypeName {
	named, ok := types.Unalias(t).(*types.Named)
	if !ok {
		return nil
	}
	if !types.IsInterface(named) {
		return nil
	}
	// Interfaces defined in the "builtin" package return nil a Pkg().
	// But they are still real interfaces that we need to make a special case for.
	// Therefore, protect gopls from panicking if a new interface type was added in the future.
	if named.Obj().Pkg() == nil && named.Obj().Name() != "error" {
		return nil
	}
	return named.Obj()
}

// concreteType tries to extract the *types.Named that defines
// the concrete type given the ast.Expr where the "missing method"
// or "conversion" errors happened. If the concrete type is something
// that cannot have methods defined on it (such as basic types), this
// method will return a nil *types.Named. The second return parameter
// is a boolean that indicates whether the concreteType was defined as a
// pointer or value.
func concreteType(e ast.Expr, info *types.Info) (*types.Named, bool) {
	tv, ok := info.Types[e]
	if !ok {
		return nil, false
	}
	typ := tv.Type
	ptr, isPtr := types.Unalias(typ).(*types.Pointer)
	if isPtr {
		typ = ptr.Elem()
	}
	named, ok := types.Unalias(typ).(*types.Named)
	if !ok {
		return nil, false
	}
	return named, isPtr
}
