// Package lexical computes the structure of the lexical environment,
// including the definition of and references to all universal,
// package-level, file-level and function-local entities.  It does not
// record qualified identifiers, labels, struct fields, or methods.
//
// It is intended for renaming and refactoring tools, which need a more
// precise understanding of identifier resolution than is available from
// the output of the type-checker alone.
//
// THIS INTERFACE IS EXPERIMENTAL AND MAY CHANGE OR BE REMOVED IN FUTURE.
//
package lexical // import "golang.org/x/tools/refactor/lexical"

// OVERVIEW
//
// As we traverse the AST, we build a "spaghetti stack" of Blocks,
// i.e. a tree with parent edges pointing to the root.  Each time we
// visit an identifier that's a reference into the lexical environment,
// we create and save an Environment, which captures the current mapping
// state of the Block; these are saved for the client.
//
// We don't bother recording non-lexical references.

// TODO(adonovan):
// - make it robust against syntax errors.  Audit all type assertions, etc.
// - better still, after the Go 1.4 thaw, move this into go/types.
//   I don't think it need be a big change since the visitor is already there;
//   we just need to records Environments.  lexical.Block is analogous
//   to types.Scope.

import (
	"fmt"
	"go/ast"
	"go/token"
	"os"
	"strconv"

	"golang.org/x/tools/go/types"
)

const trace = false

var logf = func(format string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, format, args...)
}

// A Block is a level of the lexical environment, a tree of blocks.
// It maps names to objects.
//
type Block struct {
	kind   string   // one of universe package file func block if switch typeswitch case for range
	syntax ast.Node // syntax declaring the block (nil for universe and package) [needed?]

	parent   Environment
	bindings []types.Object // bindings in lexical order
	index    map[string]int // maps a name to the index of its binding, for fast lookup
}

// An Environment is a snapshot of a Block taken at a certain lexical
// position. It may contain bindings for fewer names than the
// (completed) block, or different bindings for names that are
// re-defined later in the block.
//
// For example, the lexical Block for the function f below contains a
// binding for the local var x, but the Environments captured by at the
// two print(x) calls differ: the first contains this binding, the
// second does not.  The first Environment contains a different binding
// for x: the string var defined in the package block, an ancestor.
//
//	var x string
// 	func f() {
//		print(x)
//		x := 1
//		print(x)
//	}
//
type Environment struct {
	block     *Block
	nbindings int // length of prefix of block.bindings that's visible
}

// Depth returns the depth of this block in the block tree.
// The universal block has depth 1, a package block 2, a file block 3, etc.
func (b *Block) Depth() int {
	if b == nil {
		return 0
	}
	return 1 + b.parent.block.Depth()
}

// env returns an Environment that is a snapshot of b's current state.
func (b *Block) env() Environment {
	return Environment{b, len(b.bindings)}
}

// Lookup returns the definition of name in the environment specified by
// env, and the Block that defines it, which may be an ancestor.
func (env Environment) Lookup(name string) (types.Object, *Block) {
	if env.block == nil {
		return nil, nil
	}
	return lookup(env.block, name, env.nbindings)
}

// nbindings specifies what prefix of b.bindings should be considered visible.
func lookup(b *Block, name string, nbindings int) (types.Object, *Block) {
	if b == nil {
		return nil, nil
	}
	if i, ok := b.index[name]; ok && i < nbindings {
		return b.bindings[i], b
	}

	parent := b.parent
	if parent.block == nil {
		return nil, nil
	}
	return lookup(parent.block, name, parent.nbindings)
}

// Lookup returns the definition of name in the environment specified by
// b, and the Block that defines it, which may be an ancestor.
func (b *Block) Lookup(name string) (types.Object, *Block) {
	return b.env().Lookup(name)
}

// Block returns the block of which this environment is a partial view.
func (env Environment) Block() *Block {
	return env.block
}

func (env Environment) String() string {
	return fmt.Sprintf("%s:%d", env.block, env.nbindings)
}

func (b *Block) String() string {
	var s string
	if b.parent.block != nil {
		s = b.parent.block.String()
		s += "."
	}
	return s + b.kind
}

var universe = &Block{kind: "universe", index: make(map[string]int)}

func init() {
	for i, name := range types.Universe.Names() {
		obj := types.Universe.Lookup(name)
		universe.bindings = append(universe.bindings, obj)
		universe.index[name] = i
	}
}

// -- resolver ---------------------------------------------------------

// A Reference provides the lexical environment for a given reference to
// an object in lexical scope.
type Reference struct {
	Id  *ast.Ident
	Env Environment
}

// resolver holds the state of the identifier resolution visitation:
// the package information, the result, and the current block.
type resolver struct {
	fset    *token.FileSet
	imports map[string]*types.Package
	pkg     *types.Package
	info    *types.Info

	// visitor state
	block *Block

	result *Info
}

func (r *resolver) setBlock(kind string, syntax ast.Node) *Block {
	b := &Block{
		kind:   kind,
		syntax: syntax,
		parent: r.block.env(),
		index:  make(map[string]int),
	}
	if syntax != nil {
		r.result.Blocks[syntax] = b
	}
	r.block = b
	return b
}

func (r *resolver) qualifier(pkg *types.Package) string {
	if pkg == r.pkg {
		return "" // unqualified intra-package reference
	}
	return pkg.Path()
}

func (r *resolver) use(id *ast.Ident, env Environment) {
	if id.Name == "_" {
		return // an error
	}
	obj, _ := env.Lookup(id.Name)
	if obj == nil {
		logf("%s: lookup of %s failed\n", r.fset.Position(id.Pos()), id.Name)
	} else if want := r.info.Uses[id]; obj != want {
		// sanity check against go/types resolver
		logf("%s: internal error: lookup of %s yielded wrong object: got %v (%s), want %v\n",
			r.fset.Position(id.Pos()), id.Name, types.ObjectString(obj, r.qualifier),
			r.fset.Position(obj.Pos()),
			want)
	}
	if trace {
		logf("use %s = %v in %s\n", id.Name, types.ObjectString(obj, r.qualifier), env)
	}

	r.result.Refs[obj] = append(r.result.Refs[obj], Reference{id, env})
}

func (r *resolver) define(b *Block, id *ast.Ident) {
	obj := r.info.Defs[id]
	if obj == nil {
		logf("%s: internal error: not a defining ident: %s\n",
			r.fset.Position(id.Pos()), id.Name)
		panic(id)
	}
	r.defineObject(b, id.Name, obj)

	// Objects (other than PkgName) defined at file scope
	// are also defined in the enclosing package scope.
	if _, ok := b.syntax.(*ast.File); ok {
		switch obj.(type) {
		default:
			r.defineObject(b.parent.block, id.Name, obj)
		case nil, *types.PkgName:
		}
	}
}

// Used for implicit objects created by some ImportSpecs and CaseClauses.
func (r *resolver) defineImplicit(b *Block, n ast.Node, name string) {
	obj := r.info.Implicits[n]
	if obj == nil {
		logf("%s: internal error: not an implicit definition: %T\n",
			r.fset.Position(n.Pos()), n)
	}
	r.defineObject(b, name, obj)
}

func (r *resolver) defineObject(b *Block, name string, obj types.Object) {
	if obj.Name() == "_" {
		return
	}
	i := len(b.bindings)
	b.bindings = append(b.bindings, obj)
	b.index[name] = i
	if trace {
		logf("def %s = %s in %s\n", name, types.ObjectString(obj, r.qualifier), b)
	}
	r.result.Defs[obj] = b
}

func (r *resolver) function(recv *ast.FieldList, typ *ast.FuncType, body *ast.BlockStmt, syntax ast.Node) {
	// Use all signature types in enclosing block.
	r.expr(typ)
	r.fieldList(recv, false)

	savedBlock := r.block // save
	r.setBlock("func", syntax)

	// Define all parameters/results, and visit the body, within the func block.
	r.fieldList(typ.Params, true)
	r.fieldList(typ.Results, true)
	r.fieldList(recv, true)
	if body != nil {
		r.stmtList(body.List)
	}

	r.block = savedBlock // restore
}

func (r *resolver) fieldList(list *ast.FieldList, def bool) {
	if list != nil {
		for _, f := range list.List {
			if def {
				for _, id := range f.Names {
					r.define(r.block, id)
				}
			} else {
				r.expr(f.Type)
			}
		}
	}
}

func (r *resolver) exprList(list []ast.Expr) {
	for _, x := range list {
		r.expr(x)
	}
}

func (r *resolver) expr(n ast.Expr) {
	switch n := n.(type) {
	case *ast.BadExpr:
	case *ast.BasicLit:
		// no-op

	case *ast.Ident:
		r.use(n, r.block.env())

	case *ast.Ellipsis:
		if n.Elt != nil {
			r.expr(n.Elt)
		}

	case *ast.FuncLit:
		r.function(nil, n.Type, n.Body, n)

	case *ast.CompositeLit:
		if n.Type != nil {
			r.expr(n.Type)
		}
		tv := r.info.Types[n]
		if _, ok := deref(tv.Type).Underlying().(*types.Struct); ok {
			for _, elt := range n.Elts {
				if kv, ok := elt.(*ast.KeyValueExpr); ok {
					r.expr(kv.Value)

					// Also uses field kv.Key (non-lexical)
					//  id := kv.Key.(*ast.Ident)
					//  obj := r.info.Uses[id]
					//  logf("use %s = %v (field)\n",
					// 	id.Name, types.ObjectString(obj, r.qualifier))
					// TODO make a fake FieldVal selection?
				} else {
					r.expr(elt)
				}
			}
		} else {
			r.exprList(n.Elts)
		}

	case *ast.ParenExpr:
		r.expr(n.X)

	case *ast.SelectorExpr:
		r.expr(n.X)

		// Non-lexical reference to field/method, or qualified identifier.
		// if sel, ok := r.info.Selections[n]; ok { // selection
		// 	switch sel.Kind() {
		// 	case types.FieldVal:
		// 		logf("use %s = %v (field)\n",
		// 			n.Sel.Name, types.ObjectString(sel.Obj(), r.qualifier))
		// 	case types.MethodExpr, types.MethodVal:
		// 		logf("use %s = %v (method)\n",
		// 			n.Sel.Name, types.ObjectString(sel.Obj(), r.qualifier))
		// 	}
		// } else { // qualified identifier
		// 	obj := r.info.Uses[n.Sel]
		// 	logf("use %s = %v (qualified)\n", n.Sel.Name, obj)
		// }

	case *ast.IndexExpr:
		r.expr(n.X)
		r.expr(n.Index)

	case *ast.SliceExpr:
		r.expr(n.X)
		if n.Low != nil {
			r.expr(n.Low)
		}
		if n.High != nil {
			r.expr(n.High)
		}
		if n.Max != nil {
			r.expr(n.Max)
		}

	case *ast.TypeAssertExpr:
		r.expr(n.X)
		if n.Type != nil {
			r.expr(n.Type)
		}

	case *ast.CallExpr:
		r.expr(n.Fun)
		r.exprList(n.Args)

	case *ast.StarExpr:
		r.expr(n.X)

	case *ast.UnaryExpr:
		r.expr(n.X)

	case *ast.BinaryExpr:
		r.expr(n.X)
		r.expr(n.Y)

	case *ast.KeyValueExpr:
		r.expr(n.Key)
		r.expr(n.Value)

	case *ast.ArrayType:
		if n.Len != nil {
			r.expr(n.Len)
		}
		r.expr(n.Elt)

	case *ast.StructType:
		// Use all the type names, but don't define any fields.
		r.fieldList(n.Fields, false)

	case *ast.FuncType:
		// Use all the type names, but don't define any vars.
		r.fieldList(n.Params, false)
		r.fieldList(n.Results, false)

	case *ast.InterfaceType:
		// Use all the type names, but don't define any methods.
		r.fieldList(n.Methods, false)

	case *ast.MapType:
		r.expr(n.Key)
		r.expr(n.Value)

	case *ast.ChanType:
		r.expr(n.Value)

	default:
		panic(n)
	}
}

func (r *resolver) stmtList(list []ast.Stmt) {
	for _, s := range list {
		r.stmt(s)
	}
}

func (r *resolver) stmt(n ast.Stmt) {
	switch n := n.(type) {
	case *ast.BadStmt:
	case *ast.EmptyStmt:
		// nothing to do

	case *ast.DeclStmt:
		decl := n.Decl.(*ast.GenDecl)
		for _, spec := range decl.Specs {
			switch spec := spec.(type) {
			case *ast.ValueSpec: // const or var
				if spec.Type != nil {
					r.expr(spec.Type)
				}
				r.exprList(spec.Values)
				for _, name := range spec.Names {
					r.define(r.block, name)
				}

			case *ast.TypeSpec:
				r.define(r.block, spec.Name)
				r.expr(spec.Type)
			}
		}

	case *ast.LabeledStmt:
		// Also defines label n.Label (non-lexical)
		r.stmt(n.Stmt)

	case *ast.ExprStmt:
		r.expr(n.X)

	case *ast.SendStmt:
		r.expr(n.Chan)
		r.expr(n.Value)

	case *ast.IncDecStmt:
		r.expr(n.X)

	case *ast.AssignStmt:
		if n.Tok == token.DEFINE {
			r.exprList(n.Rhs)
			for _, lhs := range n.Lhs {
				id := lhs.(*ast.Ident)
				if _, ok := r.info.Defs[id]; ok {
					r.define(r.block, id)
				} else {
					r.use(id, r.block.env())
				}
			}
		} else { // ASSIGN
			r.exprList(n.Lhs)
			r.exprList(n.Rhs)
		}

	case *ast.GoStmt:
		r.expr(n.Call)

	case *ast.DeferStmt:
		r.expr(n.Call)

	case *ast.ReturnStmt:
		r.exprList(n.Results)

	case *ast.BranchStmt:
		if n.Label != nil {
			// Also uses label n.Label (non-lexical)
		}

	case *ast.SelectStmt:
		r.stmtList(n.Body.List)

	case *ast.BlockStmt: // (explicit blocks only)
		savedBlock := r.block // save
		r.setBlock("block", n)
		r.stmtList(n.List)
		r.block = savedBlock // restore

	case *ast.IfStmt:
		savedBlock := r.block // save
		r.setBlock("if", n)
		if n.Init != nil {
			r.stmt(n.Init)
		}
		r.expr(n.Cond)
		r.stmt(n.Body) // new block
		if n.Else != nil {
			r.stmt(n.Else)
		}
		r.block = savedBlock // restore

	case *ast.CaseClause:
		savedBlock := r.block // save
		r.setBlock("case", n)
		if obj, ok := r.info.Implicits[n]; ok {
			// e.g.
			//   switch y := x.(type) {
			//   case T: // we declare an implicit 'var y T' in this block
			//   }
			r.defineImplicit(r.block, n, obj.Name())
		}
		r.exprList(n.List)
		r.stmtList(n.Body)
		r.block = savedBlock // restore

	case *ast.SwitchStmt:
		savedBlock := r.block // save
		r.setBlock("switch", n)
		if n.Init != nil {
			r.stmt(n.Init)
		}
		if n.Tag != nil {
			r.expr(n.Tag)
		}
		r.stmtList(n.Body.List)
		r.block = savedBlock // restore

	case *ast.TypeSwitchStmt:
		savedBlock := r.block // save
		r.setBlock("typeswitch", n)
		if n.Init != nil {
			r.stmt(n.Init)
		}
		if assign, ok := n.Assign.(*ast.AssignStmt); ok { // y := x.(type)
			r.expr(assign.Rhs[0]) // skip y: not a defining ident
		} else {
			r.stmt(n.Assign)
		}
		r.stmtList(n.Body.List)
		r.block = savedBlock // restore

	case *ast.CommClause:
		savedBlock := r.block // save
		r.setBlock("case", n)
		if n.Comm != nil {
			r.stmt(n.Comm)
		}
		r.stmtList(n.Body)
		r.block = savedBlock // restore

	case *ast.ForStmt:
		savedBlock := r.block // save
		r.setBlock("for", n)
		if n.Init != nil {
			r.stmt(n.Init)
		}
		if n.Cond != nil {
			r.expr(n.Cond)
		}
		if n.Post != nil {
			r.stmt(n.Post)
		}
		r.stmt(n.Body)
		r.block = savedBlock // restore

	case *ast.RangeStmt:
		r.expr(n.X)
		savedBlock := r.block // save
		r.setBlock("range", n)
		if n.Tok == token.DEFINE {
			if n.Key != nil {
				r.define(r.block, n.Key.(*ast.Ident))
			}
			if n.Value != nil {
				r.define(r.block, n.Value.(*ast.Ident))
			}
		} else {
			if n.Key != nil {
				r.expr(n.Key)
			}
			if n.Value != nil {
				r.expr(n.Value)
			}
		}
		r.stmt(n.Body)
		r.block = savedBlock // restore

	default:
		panic(n)
	}
}

func (r *resolver) doImport(s *ast.ImportSpec, fileBlock *Block) {
	path, _ := strconv.Unquote(s.Path.Value)
	pkg := r.imports[path]
	if s.Name == nil { // normal
		r.defineImplicit(fileBlock, s, pkg.Name())
	} else if s.Name.Name == "." { // dot import
		for _, name := range pkg.Scope().Names() {
			if ast.IsExported(name) {
				obj := pkg.Scope().Lookup(name)
				r.defineObject(fileBlock, name, obj)
			}
		}
	} else { // renaming import
		r.define(fileBlock, s.Name)
	}
}

func (r *resolver) doPackage(pkg *types.Package, files []*ast.File) {
	r.block = universe
	r.result.Blocks[nil] = universe

	r.result.PackageBlock = r.setBlock("package", nil)

	var fileBlocks []*Block

	// 1. Insert all package-level objects into file and package blocks.
	//    (PkgName objects are only inserted into file blocks.)
	for _, f := range files {
		r.block = r.result.PackageBlock
		fileBlock := r.setBlock("file", f) // package is not yet visible to file
		fileBlocks = append(fileBlocks, fileBlock)

		for _, d := range f.Decls {
			switch d := d.(type) {
			case *ast.GenDecl:
				for _, s := range d.Specs {
					switch s := s.(type) {
					case *ast.ImportSpec:
						r.doImport(s, fileBlock)

					case *ast.ValueSpec: // const or var
						for _, name := range s.Names {
							r.define(r.result.PackageBlock, name)
						}

					case *ast.TypeSpec:
						r.define(r.result.PackageBlock, s.Name)
					}
				}

			case *ast.FuncDecl:
				if d.Recv == nil { // function
					if d.Name.Name != "init" {
						r.define(r.result.PackageBlock, d.Name)
					}
				}
			}
		}
	}

	// 2. Now resolve bodies of GenDecls and FuncDecls.
	for i, f := range files {
		fileBlock := fileBlocks[i]
		fileBlock.parent = r.result.PackageBlock.env() // make entire package visible to this file

		for _, d := range f.Decls {
			r.block = fileBlock

			switch d := d.(type) {
			case *ast.GenDecl:
				for _, s := range d.Specs {
					switch s := s.(type) {
					case *ast.ValueSpec: // const or var
						if s.Type != nil {
							r.expr(s.Type)
						}
						r.exprList(s.Values)

					case *ast.TypeSpec:
						r.expr(s.Type)
					}
				}

			case *ast.FuncDecl:
				r.function(d.Recv, d.Type, d.Body, d)
			}
		}
	}

	r.block = nil
}

// An Info contains the lexical reference structure of a package.
type Info struct {
	Defs         map[types.Object]*Block      // maps each object to its defining lexical block
	Refs         map[types.Object][]Reference // maps each object to the set of references to it
	Blocks       map[ast.Node]*Block          // maps declaring syntax to block; nil => universe
	PackageBlock *Block                       // the package-level lexical block
}

// Structure computes the structure of the lexical environment of the
// package specified by (pkg, info, files).
//
// The info.{Types,Defs,Uses,Implicits} maps must have been populated
// by the type-checker
//
// fset is used for logging.
//
func Structure(fset *token.FileSet, pkg *types.Package, info *types.Info, files []*ast.File) *Info {
	r := resolver{
		fset:    fset,
		imports: make(map[string]*types.Package),
		result: &Info{
			Defs:   make(map[types.Object]*Block),
			Refs:   make(map[types.Object][]Reference),
			Blocks: make(map[ast.Node]*Block),
		},
		pkg:  pkg,
		info: info,
	}

	// Build import map for just this package.
	r.imports["unsafe"] = types.Unsafe
	for _, imp := range pkg.Imports() {
		r.imports[imp.Path()] = imp
	}

	r.doPackage(pkg, files)

	return r.result
}

// -- Plundered from golang.org/x/tools/go/ssa -----------------

// deref returns a pointer's element type; otherwise it returns typ.
func deref(typ types.Type) types.Type {
	if p, ok := typ.Underlying().(*types.Pointer); ok {
		return p.Elem()
	}
	return typ
}
