// Copyright 2014 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 rename

// This file contains logic related to specifying a renaming: parsing of
// the flags as a form of query, and finding the object(s) it denotes.
// See Usage for flag details.

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/build"
	"go/parser"
	"go/token"
	"go/types"
	"log"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"golang.org/x/tools/go/buildutil"
	"golang.org/x/tools/go/loader"
)

// A spec specifies an entity to rename.
//
// It is populated from an -offset flag or -from query;
// see Usage for the allowed -from query forms.
//
type spec struct {
	// pkg is the package containing the position
	// specified by the -from or -offset flag.
	// If filename == "", our search for the 'from' entity
	// is restricted to this package.
	pkg string

	// The original name of the entity being renamed.
	// If the query had a ::from component, this is that;
	// otherwise it's the last segment, e.g.
	//   (encoding/json.Decoder).from
	//   encoding/json.from
	fromName string

	// -- The remaining fields are private to this file.  All are optional. --

	// The query's ::x suffix, if any.
	searchFor string

	// e.g. "Decoder" in "(encoding/json.Decoder).fieldOrMethod"
	//                or "encoding/json.Decoder
	pkgMember string

	// e.g. fieldOrMethod in "(encoding/json.Decoder).fieldOrMethod"
	typeMember string

	// Restricts the query to this file.
	// Implied by -from="file.go::x" and -offset flags.
	filename string

	// Byte offset of the 'from' identifier within the file named 'filename'.
	// -offset mode only.
	offset int
}

// parseFromFlag interprets the "-from" flag value as a renaming specification.
// See Usage in rename.go for valid formats.
func parseFromFlag(ctxt *build.Context, fromFlag string) (*spec, error) {
	var spec spec
	var main string // sans "::x" suffix
	switch parts := strings.Split(fromFlag, "::"); len(parts) {
	case 1:
		main = parts[0]
	case 2:
		main = parts[0]
		spec.searchFor = parts[1]
		if parts[1] == "" {
			// error
		}
	default:
		return nil, fmt.Errorf("-from %q: invalid identifier specification (see -help for formats)", fromFlag)
	}

	if strings.HasSuffix(main, ".go") {
		// main is "filename.go"
		if spec.searchFor == "" {
			return nil, fmt.Errorf("-from: filename %q must have a ::name suffix", main)
		}
		spec.filename = main
		if !buildutil.FileExists(ctxt, spec.filename) {
			return nil, fmt.Errorf("no such file: %s", spec.filename)
		}

		bp, err := buildutil.ContainingPackage(ctxt, wd, spec.filename)
		if err != nil {
			return nil, err
		}
		spec.pkg = bp.ImportPath

	} else {
		// main is one of:
		//  "importpath"
		//  "importpath".member
		//  (*"importpath".type).fieldormethod           (parens and star optional)
		if err := parseObjectSpec(&spec, main); err != nil {
			return nil, err
		}
	}

	if spec.searchFor != "" {
		spec.fromName = spec.searchFor
	}

	cwd, err := os.Getwd()
	if err != nil {
		return nil, err
	}

	// Sanitize the package.
	bp, err := ctxt.Import(spec.pkg, cwd, build.FindOnly)
	if err != nil {
		return nil, fmt.Errorf("can't find package %q", spec.pkg)
	}
	spec.pkg = bp.ImportPath

	if !isValidIdentifier(spec.fromName) {
		return nil, fmt.Errorf("-from: invalid identifier %q", spec.fromName)
	}

	if Verbose {
		log.Printf("-from spec: %+v", spec)
	}

	return &spec, nil
}

// parseObjectSpec parses main as one of the non-filename forms of
// object specification.
func parseObjectSpec(spec *spec, main string) error {
	// Parse main as a Go expression, albeit a strange one.
	e, _ := parser.ParseExpr(main)

	if pkg := parseImportPath(e); pkg != "" {
		// e.g. bytes or "encoding/json": a package
		spec.pkg = pkg
		if spec.searchFor == "" {
			return fmt.Errorf("-from %q: package import path %q must have a ::name suffix",
				main, main)
		}
		return nil
	}

	if e, ok := e.(*ast.SelectorExpr); ok {
		x := unparen(e.X)

		// Strip off star constructor, if any.
		if star, ok := x.(*ast.StarExpr); ok {
			x = star.X
		}

		if pkg := parseImportPath(x); pkg != "" {
			// package member e.g. "encoding/json".HTMLEscape
			spec.pkg = pkg              // e.g. "encoding/json"
			spec.pkgMember = e.Sel.Name // e.g. "HTMLEscape"
			spec.fromName = e.Sel.Name
			return nil
		}

		if x, ok := x.(*ast.SelectorExpr); ok {
			// field/method of type e.g. ("encoding/json".Decoder).Decode
			y := unparen(x.X)
			if pkg := parseImportPath(y); pkg != "" {
				spec.pkg = pkg               // e.g. "encoding/json"
				spec.pkgMember = x.Sel.Name  // e.g. "Decoder"
				spec.typeMember = e.Sel.Name // e.g. "Decode"
				spec.fromName = e.Sel.Name
				return nil
			}
		}
	}

	return fmt.Errorf("-from %q: invalid expression", main)
}

// parseImportPath returns the import path of the package denoted by e.
// Any import path may be represented as a string literal;
// single-segment import paths (e.g. "bytes") may also be represented as
// ast.Ident.  parseImportPath returns "" for all other expressions.
func parseImportPath(e ast.Expr) string {
	switch e := e.(type) {
	case *ast.Ident:
		return e.Name // e.g. bytes

	case *ast.BasicLit:
		if e.Kind == token.STRING {
			pkgname, _ := strconv.Unquote(e.Value)
			return pkgname // e.g. "encoding/json"
		}
	}
	return ""
}

// parseOffsetFlag interprets the "-offset" flag value as a renaming specification.
func parseOffsetFlag(ctxt *build.Context, offsetFlag string) (*spec, error) {
	var spec spec
	// Validate -offset, e.g. file.go:#123
	parts := strings.Split(offsetFlag, ":#")
	if len(parts) != 2 {
		return nil, fmt.Errorf("-offset %q: invalid offset specification", offsetFlag)
	}

	spec.filename = parts[0]
	if !buildutil.FileExists(ctxt, spec.filename) {
		return nil, fmt.Errorf("no such file: %s", spec.filename)
	}

	bp, err := buildutil.ContainingPackage(ctxt, wd, spec.filename)
	if err != nil {
		return nil, err
	}
	spec.pkg = bp.ImportPath

	for _, r := range parts[1] {
		if !isDigit(r) {
			return nil, fmt.Errorf("-offset %q: non-numeric offset", offsetFlag)
		}
	}
	spec.offset, err = strconv.Atoi(parts[1])
	if err != nil {
		return nil, fmt.Errorf("-offset %q: non-numeric offset", offsetFlag)
	}

	// Parse the file and check there's an identifier at that offset.
	fset := token.NewFileSet()
	f, err := buildutil.ParseFile(fset, ctxt, nil, wd, spec.filename, parser.ParseComments)
	if err != nil {
		return nil, fmt.Errorf("-offset %q: cannot parse file: %s", offsetFlag, err)
	}

	id := identAtOffset(fset, f, spec.offset)
	if id == nil {
		return nil, fmt.Errorf("-offset %q: no identifier at this position", offsetFlag)
	}

	spec.fromName = id.Name

	return &spec, nil
}

var wd = func() string {
	wd, err := os.Getwd()
	if err != nil {
		panic("cannot get working directory: " + err.Error())
	}
	return wd
}()

// For source trees built with 'go build', the -from or -offset
// spec identifies exactly one initial 'from' object to rename ,
// but certain proprietary build systems allow a single file to
// appear in multiple packages (e.g. the test package contains a
// copy of its library), so there may be multiple objects for
// the same source entity.

func findFromObjects(iprog *loader.Program, spec *spec) ([]types.Object, error) {
	if spec.filename != "" {
		return findFromObjectsInFile(iprog, spec)
	}

	// Search for objects defined in specified package.

	// TODO(adonovan): the iprog.ImportMap has an entry {"main": ...}
	// for main packages, even though that's not an import path.
	// Seems like a bug.
	//
	// pkg := iprog.ImportMap[spec.pkg]
	// if pkg == nil {
	// 	return fmt.Errorf("cannot find package %s", spec.pkg) // can't happen?
	// }
	// info := iprog.AllPackages[pkg]

	// Workaround: lookup by value.
	var info *loader.PackageInfo
	var pkg *types.Package
	for pkg, info = range iprog.AllPackages {
		if pkg.Path() == spec.pkg {
			break
		}
	}
	if info == nil {
		return nil, fmt.Errorf("package %q was not loaded", spec.pkg)
	}

	objects, err := findObjects(info, spec)
	if err != nil {
		return nil, err
	}
	if len(objects) > 1 {
		// ambiguous "*" scope query
		return nil, ambiguityError(iprog.Fset, objects)
	}
	return objects, nil
}

func findFromObjectsInFile(iprog *loader.Program, spec *spec) ([]types.Object, error) {
	var fromObjects []types.Object
	for _, info := range iprog.AllPackages {
		// restrict to specified filename
		// NB: under certain proprietary build systems, a given
		// filename may appear in multiple packages.
		for _, f := range info.Files {
			thisFile := iprog.Fset.File(f.Pos())
			if !sameFile(thisFile.Name(), spec.filename) {
				continue
			}
			// This package contains the query file.

			if spec.offset != 0 {
				// Search for a specific ident by file/offset.
				id := identAtOffset(iprog.Fset, f, spec.offset)
				if id == nil {
					// can't happen?
					return nil, fmt.Errorf("identifier not found")
				}
				obj := info.Uses[id]
				if obj == nil {
					obj = info.Defs[id]
					if obj == nil {
						// Ident without Object.

						// Package clause?
						pos := thisFile.Pos(spec.offset)
						_, path, _ := iprog.PathEnclosingInterval(pos, pos)
						if len(path) == 2 { // [Ident File]
							// TODO(adonovan): support this case.
							return nil, fmt.Errorf("cannot rename %q: renaming package clauses is not yet supported",
								path[1].(*ast.File).Name.Name)
						}

						// Implicit y in "switch y := x.(type) {"?
						if obj := typeSwitchVar(&info.Info, path); obj != nil {
							return []types.Object{obj}, nil
						}

						// Probably a type error.
						return nil, fmt.Errorf("cannot find object for %q", id.Name)
					}
				}
				if obj.Pkg() == nil {
					return nil, fmt.Errorf("cannot rename predeclared identifiers (%s)", obj)

				}

				fromObjects = append(fromObjects, obj)
			} else {
				// do a package-wide query
				objects, err := findObjects(info, spec)
				if err != nil {
					return nil, err
				}

				// filter results: only objects defined in thisFile
				var filtered []types.Object
				for _, obj := range objects {
					if iprog.Fset.File(obj.Pos()) == thisFile {
						filtered = append(filtered, obj)
					}
				}
				if len(filtered) == 0 {
					return nil, fmt.Errorf("no object %q declared in file %s",
						spec.fromName, spec.filename)
				} else if len(filtered) > 1 {
					return nil, ambiguityError(iprog.Fset, filtered)
				}
				fromObjects = append(fromObjects, filtered[0])
			}
			break
		}
	}
	if len(fromObjects) == 0 {
		// can't happen?
		return nil, fmt.Errorf("file %s was not part of the loaded program", spec.filename)
	}
	return fromObjects, nil
}

func typeSwitchVar(info *types.Info, path []ast.Node) types.Object {
	if len(path) > 3 {
		// [Ident AssignStmt TypeSwitchStmt...]
		if sw, ok := path[2].(*ast.TypeSwitchStmt); ok {
			// choose the first case.
			if len(sw.Body.List) > 0 {
				obj := info.Implicits[sw.Body.List[0].(*ast.CaseClause)]
				if obj != nil {
					return obj
				}
			}
		}
	}
	return nil
}

// On success, findObjects returns the list of objects named
// spec.fromName matching the spec.  On success, the result has exactly
// one element unless spec.searchFor!="", in which case it has at least one
// element.
//
func findObjects(info *loader.PackageInfo, spec *spec) ([]types.Object, error) {
	if spec.pkgMember == "" {
		if spec.searchFor == "" {
			panic(spec)
		}
		objects := searchDefs(&info.Info, spec.searchFor)
		if objects == nil {
			return nil, fmt.Errorf("no object %q declared in package %q",
				spec.searchFor, info.Pkg.Path())
		}
		return objects, nil
	}

	pkgMember := info.Pkg.Scope().Lookup(spec.pkgMember)
	if pkgMember == nil {
		return nil, fmt.Errorf("package %q has no member %q",
			info.Pkg.Path(), spec.pkgMember)
	}

	var searchFunc *types.Func
	if spec.typeMember == "" {
		// package member
		if spec.searchFor == "" {
			return []types.Object{pkgMember}, nil
		}

		// Search within pkgMember, which must be a function.
		searchFunc, _ = pkgMember.(*types.Func)
		if searchFunc == nil {
			return nil, fmt.Errorf("cannot search for %q within %s %q",
				spec.searchFor, objectKind(pkgMember), pkgMember)
		}
	} else {
		// field/method of type
		// e.g. (encoding/json.Decoder).Decode
		// or ::x within it.

		tName, _ := pkgMember.(*types.TypeName)
		if tName == nil {
			return nil, fmt.Errorf("%s.%s is a %s, not a type",
				info.Pkg.Path(), pkgMember.Name(), objectKind(pkgMember))
		}

		// search within named type.
		obj, _, _ := types.LookupFieldOrMethod(tName.Type(), true, info.Pkg, spec.typeMember)
		if obj == nil {
			return nil, fmt.Errorf("cannot find field or method %q of %s %s.%s",
				spec.typeMember, typeKind(tName.Type()), info.Pkg.Path(), tName.Name())
		}

		if spec.searchFor == "" {
			// If it is an embedded field, return the type of the field.
			if v, ok := obj.(*types.Var); ok && v.Anonymous() {
				switch t := v.Type().(type) {
				case *types.Pointer:
					return []types.Object{t.Elem().(*types.Named).Obj()}, nil
				case *types.Named:
					return []types.Object{t.Obj()}, nil
				}
			}
			return []types.Object{obj}, nil
		}

		searchFunc, _ = obj.(*types.Func)
		if searchFunc == nil {
			return nil, fmt.Errorf("cannot search for local name %q within %s (%s.%s).%s; need a function",
				spec.searchFor, objectKind(obj), info.Pkg.Path(), tName.Name(),
				obj.Name())
		}
		if isInterface(tName.Type()) {
			return nil, fmt.Errorf("cannot search for local name %q within abstract method (%s.%s).%s",
				spec.searchFor, info.Pkg.Path(), tName.Name(), searchFunc.Name())
		}
	}

	// -- search within function or method --

	decl := funcDecl(info, searchFunc)
	if decl == nil {
		return nil, fmt.Errorf("cannot find syntax for %s", searchFunc) // can't happen?
	}

	var objects []types.Object
	for _, obj := range searchDefs(&info.Info, spec.searchFor) {
		// We use positions, not scopes, to determine whether
		// the obj is within searchFunc.  This is clumsy, but the
		// alternative, using the types.Scope tree, doesn't
		// account for non-lexical objects like fields and
		// interface methods.
		if decl.Pos() <= obj.Pos() && obj.Pos() < decl.End() && obj != searchFunc {
			objects = append(objects, obj)
		}
	}
	if objects == nil {
		return nil, fmt.Errorf("no local definition of %q within %s",
			spec.searchFor, searchFunc)
	}
	return objects, nil
}

func funcDecl(info *loader.PackageInfo, fn *types.Func) *ast.FuncDecl {
	for _, f := range info.Files {
		for _, d := range f.Decls {
			if d, ok := d.(*ast.FuncDecl); ok && info.Defs[d.Name] == fn {
				return d
			}
		}
	}
	return nil
}

func searchDefs(info *types.Info, name string) []types.Object {
	var objects []types.Object
	for id, obj := range info.Defs {
		if obj == nil {
			// e.g. blank ident.
			// TODO(adonovan): but also implicit y in
			//    switch y := x.(type)
			// Needs some thought.
			continue
		}
		if id.Name == name {
			objects = append(objects, obj)
		}
	}
	return objects
}

func identAtOffset(fset *token.FileSet, f *ast.File, offset int) *ast.Ident {
	var found *ast.Ident
	ast.Inspect(f, func(n ast.Node) bool {
		if id, ok := n.(*ast.Ident); ok {
			idpos := fset.Position(id.Pos()).Offset
			if idpos <= offset && offset < idpos+len(id.Name) {
				found = id
			}
		}
		return found == nil // keep traversing only until found
	})
	return found
}

// ambiguityError returns an error describing an ambiguous "*" scope query.
func ambiguityError(fset *token.FileSet, objects []types.Object) error {
	var buf bytes.Buffer
	for i, obj := range objects {
		if i > 0 {
			buf.WriteString(", ")
		}
		posn := fset.Position(obj.Pos())
		fmt.Fprintf(&buf, "%s at %s:%d",
			objectKind(obj), filepath.Base(posn.Filename), posn.Column)
	}
	return fmt.Errorf("ambiguous specifier %s matches %s",
		objects[0].Name(), buf.String())
}
