// 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 FromFlagUsage for details.

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

	"llvm.org/llgo/third_party/go.tools/go/buildutil"
	"llvm.org/llgo/third_party/go.tools/go/loader"
	"llvm.org/llgo/third_party/go.tools/go/types"
)

// A spec specifies an entity to rename.
//
// It is populated from an -offset flag or -from query; see
// FromFlagUsage 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
}

const FromFlagUsage = `
A legal -from query has one of the following forms:

  "encoding/json".Decoder.Decode	method of package-level named type
  (*"encoding/json".Decoder).Decode	ditto, alternative syntax
  "encoding/json".Decoder.buf           field of package-level named struct type
  "encoding/json".HTMLEscape            package member (const, func, var, type)
  "encoding/json".Decoder.Decode::x     local object x within a method
  "encoding/json".HTMLEscape::x         local object x within a function
  "encoding/json"::x                    object x anywhere within a package
  json.go::x                            object x within file json.go

  For methods, the parens and '*' on the receiver type are both optional.

  Double-quotes may be omitted for single-segment import paths such as
  fmt.  They may need to be escaped when writing a shell command.

  It is an error if one of the ::x queries matches multiple objects.
`

// parseFromFlag interprets the "-from" flag value as a renaming specification.
// See FromFlagUsage 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
	}

	// Sanitize the package.
	// TODO(adonovan): test with relative packages.  May need loader changes.
	bp, err := ctxt.Import(spec.pkg, ".", 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 {
		fmt.Fprintf(os.Stderr, "-from spec: %+v\n", 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.
	//
	// pkgObj := iprog.ImportMap[spec.pkg]
	// if pkgObj == nil {
	// 	return fmt.Errorf("cannot find package %s", spec.pkg) // can't happen?
	// }

	// Workaround: lookup by value.
	var pkgObj *types.Package
	for pkg := range iprog.AllPackages {
		if pkg.Path() == spec.pkg {
			pkgObj = pkg
			break
		}
	}
	info := iprog.AllPackages[pkgObj]

	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 == "" {
			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())
}
