// 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 i := 0; i < named.NumMethods(); i++ {
			concreteFuncs[named.Method(i).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 i := 0; i < ifaceType.NumMethods(); i++ {
		imethod := ifaceType.Method(i)
		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 i := 0; i < named.NumMethods(); i++ {
			if recv := named.Method(i).Type().(*types.Signature).Recv(); recv.Name() != "" {
				rn = recv.Name()
				break
			}
		}
	}

	// Check for receiver name conflicts
	checkRecvName := func(tuple *types.Tuple) bool {
		for i := 0; i < tuple.Len(); i++ {
			if rn == tuple.At(i).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
}
