// Copyright 2013 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.

// +build go1.5

package oracle

import (
	"fmt"
	"go/ast"
	"go/token"
	"go/types"
	"reflect"
	"sort"
	"strings"

	"golang.org/x/tools/go/loader"
	"golang.org/x/tools/go/types/typeutil"
	"golang.org/x/tools/oracle/serial"
	"golang.org/x/tools/refactor/importgraph"
)

// Implements displays the "implements" relation as it pertains to the
// selected type.
// If the selection is a method, 'implements' displays
// the corresponding methods of the types that would have been reported
// by an implements query on the receiver type.
//
func implements(q *Query) error {
	lconf := loader.Config{Build: q.Build}
	allowErrors(&lconf)

	qpkg, err := importQueryPackage(q.Pos, &lconf)
	if err != nil {
		return err
	}

	// Set the packages to search.
	if len(q.Scope) > 0 {
		// Inspect all packages in the analysis scope, if specified.
		if err := setPTAScope(&lconf, q.Scope); err != nil {
			return err
		}
	} else {
		// Otherwise inspect the forward and reverse
		// transitive closure of the selected package.
		// (In theory even this is incomplete.)
		_, rev, _ := importgraph.Build(q.Build)
		for path := range rev.Search(qpkg) {
			lconf.ImportWithTests(path)
		}

		// TODO(adonovan): for completeness, we should also
		// type-check and inspect function bodies in all
		// imported packages.  This would be expensive, but we
		// could optimize by skipping functions that do not
		// contain type declarations.  This would require
		// changing the loader's TypeCheckFuncBodies hook to
		// provide the []*ast.File.
	}

	// Load/parse/type-check the program.
	lprog, err := lconf.Load()
	if err != nil {
		return err
	}
	q.Fset = lprog.Fset

	qpos, err := parseQueryPos(lprog, q.Pos, false)
	if err != nil {
		return err
	}

	// Find the selected type.
	path, action := findInterestingNode(qpos.info, qpos.path)

	var method *types.Func
	var T types.Type // selected type (receiver if method != nil)

	switch action {
	case actionExpr:
		// method?
		if id, ok := path[0].(*ast.Ident); ok {
			if obj, ok := qpos.info.ObjectOf(id).(*types.Func); ok {
				recv := obj.Type().(*types.Signature).Recv()
				if recv == nil {
					return fmt.Errorf("this function is not a method")
				}
				method = obj
				T = recv.Type()
			}
		}
	case actionType:
		T = qpos.info.TypeOf(path[0].(ast.Expr))
	}
	if T == nil {
		return fmt.Errorf("no type or method here")
	}

	// Find all named types, even local types (which can have
	// methods via promotion) and the built-in "error".
	var allNamed []types.Type
	for _, info := range lprog.AllPackages {
		for _, obj := range info.Defs {
			if obj, ok := obj.(*types.TypeName); ok {
				allNamed = append(allNamed, obj.Type())
			}
		}
	}
	allNamed = append(allNamed, types.Universe.Lookup("error").Type())

	var msets typeutil.MethodSetCache

	// Test each named type.
	var to, from, fromPtr []types.Type
	for _, U := range allNamed {
		if isInterface(T) {
			if msets.MethodSet(T).Len() == 0 {
				continue // empty interface
			}
			if isInterface(U) {
				if msets.MethodSet(U).Len() == 0 {
					continue // empty interface
				}

				// T interface, U interface
				if !types.Identical(T, U) {
					if types.AssignableTo(U, T) {
						to = append(to, U)
					}
					if types.AssignableTo(T, U) {
						from = append(from, U)
					}
				}
			} else {
				// T interface, U concrete
				if types.AssignableTo(U, T) {
					to = append(to, U)
				} else if pU := types.NewPointer(U); types.AssignableTo(pU, T) {
					to = append(to, pU)
				}
			}
		} else if isInterface(U) {
			if msets.MethodSet(U).Len() == 0 {
				continue // empty interface
			}

			// T concrete, U interface
			if types.AssignableTo(T, U) {
				from = append(from, U)
			} else if pT := types.NewPointer(T); types.AssignableTo(pT, U) {
				fromPtr = append(fromPtr, U)
			}
		}
	}

	var pos interface{} = qpos
	if nt, ok := deref(T).(*types.Named); ok {
		pos = nt.Obj()
	}

	// Sort types (arbitrarily) to ensure test determinism.
	sort.Sort(typesByString(to))
	sort.Sort(typesByString(from))
	sort.Sort(typesByString(fromPtr))

	var toMethod, fromMethod, fromPtrMethod []*types.Selection // contain nils
	if method != nil {
		for _, t := range to {
			toMethod = append(toMethod,
				types.NewMethodSet(t).Lookup(method.Pkg(), method.Name()))
		}
		for _, t := range from {
			fromMethod = append(fromMethod,
				types.NewMethodSet(t).Lookup(method.Pkg(), method.Name()))
		}
		for _, t := range fromPtr {
			fromPtrMethod = append(fromPtrMethod,
				types.NewMethodSet(t).Lookup(method.Pkg(), method.Name()))
		}
	}

	q.result = &implementsResult{
		qpos, T, pos, to, from, fromPtr, method, toMethod, fromMethod, fromPtrMethod,
	}
	return nil
}

type implementsResult struct {
	qpos *queryPos

	t       types.Type   // queried type (not necessarily named)
	pos     interface{}  // pos of t (*types.Name or *QueryPos)
	to      []types.Type // named or ptr-to-named types assignable to interface T
	from    []types.Type // named interfaces assignable from T
	fromPtr []types.Type // named interfaces assignable only from *T

	// if a method was queried:
	method        *types.Func        // queried method
	toMethod      []*types.Selection // method of type to[i], if any
	fromMethod    []*types.Selection // method of type from[i], if any
	fromPtrMethod []*types.Selection // method of type fromPtrMethod[i], if any
}

func (r *implementsResult) display(printf printfFunc) {
	relation := "is implemented by"

	meth := func(sel *types.Selection) {
		if sel != nil {
			printf(sel.Obj(), "\t%s method (%s).%s",
				relation, r.qpos.typeString(sel.Recv()), sel.Obj().Name())
		}
	}

	if isInterface(r.t) {
		if types.NewMethodSet(r.t).Len() == 0 { // TODO(adonovan): cache mset
			printf(r.pos, "empty interface type %s", r.qpos.typeString(r.t))
			return
		}

		if r.method == nil {
			printf(r.pos, "interface type %s", r.qpos.typeString(r.t))
		} else {
			printf(r.method, "abstract method %s", r.qpos.objectString(r.method))
		}

		// Show concrete types (or methods) first; use two passes.
		for i, sub := range r.to {
			if !isInterface(sub) {
				if r.method == nil {
					printf(deref(sub).(*types.Named).Obj(), "\t%s %s type %s",
						relation, typeKind(sub), r.qpos.typeString(sub))
				} else {
					meth(r.toMethod[i])
				}
			}
		}
		for i, sub := range r.to {
			if isInterface(sub) {
				if r.method == nil {
					printf(sub.(*types.Named).Obj(), "\t%s %s type %s",
						relation, typeKind(sub), r.qpos.typeString(sub))
				} else {
					meth(r.toMethod[i])
				}
			}
		}

		relation = "implements"
		for i, super := range r.from {
			if r.method == nil {
				printf(super.(*types.Named).Obj(), "\t%s %s",
					relation, r.qpos.typeString(super))
			} else {
				meth(r.fromMethod[i])
			}
		}
	} else {
		relation = "implements"

		if r.from != nil {
			if r.method == nil {
				printf(r.pos, "%s type %s",
					typeKind(r.t), r.qpos.typeString(r.t))
			} else {
				printf(r.method, "concrete method %s",
					r.qpos.objectString(r.method))
			}
			for i, super := range r.from {
				if r.method == nil {
					printf(super.(*types.Named).Obj(), "\t%s %s",
						relation, r.qpos.typeString(super))
				} else {
					meth(r.fromMethod[i])
				}
			}
		}
		if r.fromPtr != nil {
			if r.method == nil {
				printf(r.pos, "pointer type *%s", r.qpos.typeString(r.t))
			} else {
				// TODO(adonovan): de-dup (C).f and (*C).f implementing (I).f.
				printf(r.method, "concrete method %s",
					r.qpos.objectString(r.method))
			}

			for i, psuper := range r.fromPtr {
				if r.method == nil {
					printf(psuper.(*types.Named).Obj(), "\t%s %s",
						relation, r.qpos.typeString(psuper))
				} else {
					meth(r.fromPtrMethod[i])
				}
			}
		} else if r.from == nil {
			printf(r.pos, "%s type %s implements only interface{}",
				typeKind(r.t), r.qpos.typeString(r.t))
		}
	}
}

func (r *implementsResult) toSerial(res *serial.Result, fset *token.FileSet) {
	res.Implements = &serial.Implements{
		T:                       makeImplementsType(r.t, fset),
		AssignableTo:            makeImplementsTypes(r.to, fset),
		AssignableFrom:          makeImplementsTypes(r.from, fset),
		AssignableFromPtr:       makeImplementsTypes(r.fromPtr, fset),
		AssignableToMethod:      methodsToSerial(r.qpos.info.Pkg, r.toMethod, fset),
		AssignableFromMethod:    methodsToSerial(r.qpos.info.Pkg, r.fromMethod, fset),
		AssignableFromPtrMethod: methodsToSerial(r.qpos.info.Pkg, r.fromPtrMethod, fset),
	}
	if r.method != nil {
		res.Implements.Method = &serial.DescribeMethod{
			Name: r.qpos.objectString(r.method),
			Pos:  fset.Position(r.method.Pos()).String(),
		}
	}
}

func makeImplementsTypes(tt []types.Type, fset *token.FileSet) []serial.ImplementsType {
	var r []serial.ImplementsType
	for _, t := range tt {
		r = append(r, makeImplementsType(t, fset))
	}
	return r
}

func makeImplementsType(T types.Type, fset *token.FileSet) serial.ImplementsType {
	var pos token.Pos
	if nt, ok := deref(T).(*types.Named); ok { // implementsResult.t may be non-named
		pos = nt.Obj().Pos()
	}
	return serial.ImplementsType{
		Name: T.String(),
		Pos:  fset.Position(pos).String(),
		Kind: typeKind(T),
	}
}

// typeKind returns a string describing the underlying kind of type,
// e.g. "slice", "array", "struct".
func typeKind(T types.Type) string {
	s := reflect.TypeOf(T.Underlying()).String()
	return strings.ToLower(strings.TrimPrefix(s, "*types."))
}

func isInterface(T types.Type) bool { return types.IsInterface(T) }

type typesByString []types.Type

func (p typesByString) Len() int           { return len(p) }
func (p typesByString) Less(i, j int) bool { return p[i].String() < p[j].String() }
func (p typesByString) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
