// Copyright 2020 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 go2go

import (
	"bufio"
	"fmt"
	"go/ast"
	"go/printer"
	"go/token"
	"go/types"
	"os"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
)

var config = printer.Config{
	Mode:     printer.UseSpaces | printer.TabIndent | printer.SourcePos,
	Tabwidth: 8,
}

// isParameterizedFuncDecl reports whether fd is a parameterized function.
func isParameterizedFuncDecl(fd *ast.FuncDecl, info *types.Info) bool {
	if fd.Type.TParams != nil && len(fd.Type.TParams.List) > 0 {
		return true
	}
	if fd.Recv != nil {
		rtyp := info.TypeOf(fd.Recv.List[0].Type)
		if rtyp == nil {
			// Already instantiated.
			return false
		}
		if p, ok := rtyp.(*types.Pointer); ok {
			rtyp = p.Elem()
		}
		if named, ok := rtyp.(*types.Named); ok {
			if named.TParams() != nil {
				return true
			}
		}
	}
	return false
}

// isTranslatableType reports whether a type spec can be translated to Go1.
// This is false if the type spec relies on any features that use generics.
func isTranslatableType(s ast.Spec, info *types.Info) bool {
	if isParameterizedTypeDecl(s, info) {
		return false
	}
	if isTypeBound(s, info) {
		return false
	}
	if embedsComparable(s, info) {
		return false
	}
	return true
}

// isParameterizedTypeDecl reports whether s is a parameterized type.
func isParameterizedTypeDecl(s ast.Spec, info *types.Info) bool {
	ts := s.(*ast.TypeSpec)
	if ts.TParams != nil && len(ts.TParams.List) > 0 {
		return true
	}
	if ts.Assign == token.NoPos {
		return false
	}

	// This is a type alias. Try to resolve it.
	typ := info.TypeOf(ts.Type)
	if typ == nil {
		return false
	}
	named, ok := typ.(*types.Named)
	if !ok {
		return false
	}
	return len(named.TParams()) > 0 && len(named.TArgs()) == 0
}

// isTypeBound reports whether s is an interface type that includes a
// type bound or that embeds an interface that must be a type bound.
func isTypeBound(s ast.Spec, info *types.Info) bool {
	typ := info.TypeOf(s.(*ast.TypeSpec).Type)
	if typ == nil {
		return false
	}
	if iface, ok := typ.Underlying().(*types.Interface); ok {
		if iface.HasTypeList() {
			return true
		}
	}
	return false
}

// embedsComparable reports whether s is an interface type that embeds
// the predeclared type "comparable", directly or indirectly.
func embedsComparable(s ast.Spec, info *types.Info) bool {
	typ := info.TypeOf(s.(*ast.TypeSpec).Type)
	return typeEmbedsComparable(typ)
}

// typeEmbedsComparable reports whether typ is an interface type
// that embeds the predeclared type "comparable", directly or indirectly.
// This is like embedsComparable, but for a types.Type.
func typeEmbedsComparable(typ types.Type) bool {
	if typ == nil {
		return false
	}
	iface, ok := typ.Underlying().(*types.Interface)
	if !ok {
		return false
	}
	n := iface.NumEmbeddeds()
	if n == 0 {
		return false
	}
	comparable := types.Universe.Lookup("comparable")
	for i := 0; i < n; i++ {
		et := iface.EmbeddedType(i)
		if named, ok := et.(*types.Named); ok && named.Obj() == comparable {
			return true
		}
		if typeEmbedsComparable(et) {
			return true
		}
	}
	return false
}

// A translator is used to translate a file from generic Go to Go 1.
type translator struct {
	fset         *token.FileSet
	importer     *Importer
	tpkg         *types.Package
	types        map[ast.Expr]types.Type
	newDecls     []ast.Decl
	typePackages map[*types.Package]bool

	// typeDepth tracks recursive type instantiations.
	typeDepth int

	// err is set if we have seen an error during this translation.
	// This is used by the rewrite methods.
	err error
}

// instantiations tracks all function and type instantiations for a package.
type instantiations struct {
	funcInstantiations map[string][]*funcInstantiation
	typeInstantiations map[types.Type][]*typeInstantiation
}

// A funcInstantiation is a single instantiation of a function.
type funcInstantiation struct {
	types []types.Type
	decl  *ast.Ident
}

// A typeInstantiation is a single instantiation of a type.
type typeInstantiation struct {
	types      []types.Type
	decl       *ast.Ident
	typ        types.Type
	inProgress bool
}

// funcInstantiations fetches the function instantiations defined in
// the current package, given a generic function name.
func (t *translator) funcInstantiations(key string) []*funcInstantiation {
	insts := t.importer.instantiations[t.tpkg]
	if insts == nil {
		return nil
	}
	return insts.funcInstantiations[key]
}

// addFuncInstantiation adds a new function instantiation.
func (t *translator) addFuncInstantiation(key string, inst *funcInstantiation) {
	insts := t.pkgInstantiations()
	insts.funcInstantiations[key] = append(insts.funcInstantiations[key], inst)
}

// typeInstantiations fetches the type instantiations defined in
// the current package, given a generic type.
func (t *translator) typeInstantiations(typ types.Type) []*typeInstantiation {
	insts := t.importer.instantiations[t.tpkg]
	if insts == nil {
		return nil
	}
	return insts.typeInstantiations[typ]
}

// addTypeInstantiations adds a new type instantiation.
func (t *translator) addTypeInstantiation(typ types.Type, inst *typeInstantiation) {
	insts := t.pkgInstantiations()
	insts.typeInstantiations[typ] = append(insts.typeInstantiations[typ], inst)
}

// pkgInstantiations returns the instantiations structure for the current
// package, creating it if necessary.
func (t *translator) pkgInstantiations() *instantiations {
	insts := t.importer.instantiations[t.tpkg]
	if insts == nil {
		insts = &instantiations{
			funcInstantiations: make(map[string][]*funcInstantiation),
			typeInstantiations: make(map[types.Type][]*typeInstantiation),
		}
		t.importer.instantiations[t.tpkg] = insts
	}
	return insts
}

// rewrite rewrites the contents of one file.
func rewriteFile(dir string, fset *token.FileSet, importer *Importer, importPath string, tpkg *types.Package, filename string, file *ast.File, addImportableName bool) (err error) {
	if err := rewriteAST(fset, importer, importPath, tpkg, file, addImportableName); err != nil {
		return err
	}

	filename = filepath.Base(filename)
	goFile := strings.TrimSuffix(filename, filepath.Ext(filename)) + ".go"
	o, err := os.Create(filepath.Join(dir, goFile))
	if err != nil {
		return err
	}
	defer func() {
		if closeErr := o.Close(); err == nil {
			err = closeErr
		}
	}()

	w := bufio.NewWriter(o)
	defer func() {
		if flushErr := w.Flush(); err == nil {
			err = flushErr
		}
	}()
	fmt.Fprintln(w, rewritePrefix)

	return config.Fprint(w, fset, file)
}

// rewriteAST rewrites the AST for a file.
func rewriteAST(fset *token.FileSet, importer *Importer, importPath string, tpkg *types.Package, file *ast.File, addImportableName bool) (err error) {
	t := translator{
		fset:         fset,
		importer:     importer,
		tpkg:         tpkg,
		types:        make(map[ast.Expr]types.Type),
		typePackages: make(map[*types.Package]bool),
	}
	t.translate(file)

	// Add all the transitive imports. This is more than we need,
	// but we're not trying to be elegant here.
	imps := make(map[string]bool)

	for _, p := range importer.transitiveImports(importPath) {
		imps[p] = true
	}
	for pkg := range t.typePackages {
		if pkg != t.tpkg {
			imps[pkg.Path()] = true
		}
	}

	decls := make([]ast.Decl, 0, len(file.Decls))
	var specs []ast.Spec
	for _, decl := range file.Decls {
		gen, ok := decl.(*ast.GenDecl)
		if !ok || gen.Tok != token.IMPORT {
			decls = append(decls, decl)
			continue
		}
		for _, spec := range gen.Specs {
			imp := spec.(*ast.ImportSpec)
			if imp.Name != nil {
				specs = append(specs, imp)
			}
			// We picked up Go 2 imports above, but we still
			// need to pick up Go 1 imports here.
			path, err := strconv.Unquote(imp.Path.Value)
			if err != nil || imps[path] {
				continue
			}
			if imp.Name == nil {
				// If Name != nil we are keeping the spec.
				// Don't add the import again here,
				// only if it is needed elsewhere.
				imps[path] = true
			}
			for _, p := range importer.transitiveImports(path) {
				imps[p] = true
			}
		}
	}
	file.Decls = decls

	// If we have a ./ import, let it override a standard import
	// we may have added due to t.typePackages.
	for path := range imps {
		if strings.HasPrefix(path, "./") {
			delete(imps, strings.TrimPrefix(path, "./"))
		}
	}

	paths := make([]string, 0, len(imps))
	for p := range imps {
		paths = append(paths, p)
	}
	sort.Strings(paths)

	for _, p := range paths {
		specs = append(specs, ast.Spec(&ast.ImportSpec{
			Path: &ast.BasicLit{
				Kind:  token.STRING,
				Value: strconv.Quote(p),
			},
		}))
	}
	if len(specs) > 0 {
		first := &ast.GenDecl{
			Tok:   token.IMPORT,
			Specs: specs,
		}
		file.Decls = append([]ast.Decl{first}, file.Decls...)
	}

	// Add a name that other packages can reference to avoid an error
	// about an unused package.
	if addImportableName {
		file.Decls = append(file.Decls,
			&ast.GenDecl{
				Tok: token.TYPE,
				Specs: []ast.Spec{
					&ast.TypeSpec{
						Name: ast.NewIdent(t.importableName()),
						Type: ast.NewIdent("int"),
					},
				},
			})
	}

	// Add a reference for each imported package to avoid an error
	// about an unused package.
	for _, decl := range file.Decls {
		gen, ok := decl.(*ast.GenDecl)
		if !ok || gen.Tok != token.IMPORT {
			continue
		}
		for _, spec := range gen.Specs {
			imp := spec.(*ast.ImportSpec)
			if imp.Name != nil && imp.Name.Name == "_" {
				continue
			}
			path := strings.TrimPrefix(strings.TrimSuffix(imp.Path.Value, `"`), `"`)
			var pname string

			var tok token.Token
			var importableName string
			if pkg, ok := importer.lookupPackage(path); ok {
				tok = token.TYPE
				importableName = t.importableName()
				pname = pkg.Name()
			} else {
				fileDir := filepath.Dir(fset.Position(file.Name.Pos()).Filename)
				pkg, err := importer.ImportFrom(path, fileDir, 0)
				if err != nil {
					return err
				}
				scope := pkg.Scope()
				pname = pkg.Name()
				names := scope.Names()
			nameLoop:
				for _, name := range names {
					if !token.IsExported(name) {
						continue
					}
					obj := scope.Lookup(name)
					switch obj.(type) {
					case *types.TypeName:
						tok = token.TYPE
						importableName = name
						break nameLoop
					case *types.Var, *types.Func:
						tok = token.VAR
						importableName = name
						break nameLoop
					case *types.Const:
						tok = token.CONST
						importableName = name
						break nameLoop
					}
				}
				if importableName == "" {
					return fmt.Errorf("can't find any importable name in package %q", path)
				}
			}

			var name string
			if imp.Name != nil {
				name = imp.Name.Name
			} else {
				name = pname
			}
			var spec ast.Spec
			switch tok {
			case token.CONST, token.VAR:
				spec = &ast.ValueSpec{
					Names: []*ast.Ident{
						ast.NewIdent("_"),
					},
					Values: []ast.Expr{
						&ast.SelectorExpr{
							X:   ast.NewIdent(name),
							Sel: ast.NewIdent(importableName),
						},
					},
				}
			case token.TYPE:
				spec = &ast.TypeSpec{
					Name: ast.NewIdent("_"),
					Type: &ast.SelectorExpr{
						X:   ast.NewIdent(name),
						Sel: ast.NewIdent(importableName),
					},
				}
			default:
				panic("can't happen")
			}
			file.Decls = append(file.Decls,
				&ast.GenDecl{
					Tok:   tok,
					Specs: []ast.Spec{spec},
				})
		}
	}

	return t.err
}

// translate translates the AST for a file from generic Go to Go 1.
func (t *translator) translate(file *ast.File) {
	declsToDo := file.Decls
	file.Decls = nil
	c := 0
	for len(declsToDo) > 0 {
		if c > 50 {
			var sb strings.Builder
			printer.Fprint(&sb, t.fset, declsToDo[0])
			t.err = fmt.Errorf("looping while expanding %v", &sb)
			return
		}
		c++

		newDecls := make([]ast.Decl, 0, len(declsToDo))
		for i, decl := range declsToDo {
			switch decl := decl.(type) {
			case *ast.FuncDecl:
				if !isParameterizedFuncDecl(decl, t.importer.info) {
					t.translateFuncDecl(&declsToDo[i])
					newDecls = append(newDecls, decl)
				}
			case *ast.GenDecl:
				switch decl.Tok {
				case token.TYPE:
					newSpecs := make([]ast.Spec, 0, len(decl.Specs))
					for j := range decl.Specs {
						if isTranslatableType(decl.Specs[j], t.importer.info) {
							t.translateTypeSpec(&decl.Specs[j])
							newSpecs = append(newSpecs, decl.Specs[j])
						}
					}
					if len(newSpecs) == 0 {
						decl = nil
					} else {
						decl.Specs = newSpecs
					}
				case token.VAR, token.CONST:
					for j := range decl.Specs {
						t.translateValueSpec(&decl.Specs[j])
					}
				}
				if decl != nil {
					newDecls = append(newDecls, decl)
				}
			default:
				newDecls = append(newDecls, decl)
			}
		}
		file.Decls = append(file.Decls, newDecls...)
		declsToDo = t.newDecls
		t.newDecls = nil
	}
}

// translateTypeSpec translates a type from generic Go to Go 1.
func (t *translator) translateTypeSpec(ps *ast.Spec) {
	ts := (*ps).(*ast.TypeSpec)
	if ts.TParams != nil && len(ts.TParams.List) > 0 {
		t.err = fmt.Errorf("%s: go2go tool does not support parameterized type here", t.fset.Position((*ps).Pos()))
		return
	}
	t.translateExpr(&ts.Type)
}

// translateValueSpec translates a variable or constant from generic Go to Go 1.
func (t *translator) translateValueSpec(ps *ast.Spec) {
	vs := (*ps).(*ast.ValueSpec)
	t.translateExpr(&vs.Type)
	for i := range vs.Values {
		t.translateExpr(&vs.Values[i])
	}
}

// translateFuncDecl translates a function from generic Go to Go 1.
func (t *translator) translateFuncDecl(pd *ast.Decl) {
	if t.err != nil {
		return
	}
	fd := (*pd).(*ast.FuncDecl)
	if fd.Type.TParams != nil {
		if len(fd.Type.TParams.List) > 0 {
			panic("parameterized function")
		}
		fd.Type.TParams = nil
	}
	if fd.Recv != nil {
		t.translateFieldList(fd.Recv)
	}
	t.translateFieldList(fd.Type.Params)
	t.translateFieldList(fd.Type.Results)
	t.translateBlockStmt(fd.Body)
}

// translateBlockStmt translates a block statement from generic Go to Go 1.
func (t *translator) translateBlockStmt(pbs *ast.BlockStmt) {
	if pbs == nil {
		return
	}
	for i := range pbs.List {
		t.translateStmt(&pbs.List[i])
	}
}

// translateStmt translates a statement from generic Go to Go 1.
func (t *translator) translateStmt(ps *ast.Stmt) {
	if t.err != nil {
		return
	}
	if *ps == nil {
		return
	}
	switch s := (*ps).(type) {
	case *ast.DeclStmt:
		d := s.Decl.(*ast.GenDecl)
		switch d.Tok {
		case token.TYPE:
			for i := range d.Specs {
				t.translateTypeSpec(&d.Specs[i])
			}
		case token.CONST, token.VAR:
			for i := range d.Specs {
				t.translateValueSpec(&d.Specs[i])
			}
		default:
			panic(fmt.Sprintf("unknown decl type %v", d.Tok))
		}
	case *ast.EmptyStmt:
	case *ast.LabeledStmt:
		t.translateStmt(&s.Stmt)
	case *ast.ExprStmt:
		t.translateExpr(&s.X)
	case *ast.SendStmt:
		t.translateExpr(&s.Chan)
		t.translateExpr(&s.Value)
	case *ast.IncDecStmt:
		t.translateExpr(&s.X)
	case *ast.AssignStmt:
		t.translateExprList(s.Lhs)
		t.translateExprList(s.Rhs)
	case *ast.GoStmt:
		e := ast.Expr(s.Call)
		t.translateExpr(&e)
		s.Call = e.(*ast.CallExpr)
	case *ast.DeferStmt:
		e := ast.Expr(s.Call)
		t.translateExpr(&e)
		s.Call = e.(*ast.CallExpr)
	case *ast.ReturnStmt:
		t.translateExprList(s.Results)
	case *ast.BranchStmt:
	case *ast.BlockStmt:
		t.translateBlockStmt(s)
	case *ast.IfStmt:
		t.translateStmt(&s.Init)
		t.translateExpr(&s.Cond)
		t.translateBlockStmt(s.Body)
		t.translateStmt(&s.Else)
	case *ast.CaseClause:
		t.translateExprList(s.List)
		t.translateStmtList(s.Body)
	case *ast.SwitchStmt:
		t.translateStmt(&s.Init)
		t.translateExpr(&s.Tag)
		t.translateBlockStmt(s.Body)
	case *ast.TypeSwitchStmt:
		t.translateStmt(&s.Init)
		t.translateStmt(&s.Assign)
		t.translateBlockStmt(s.Body)
	case *ast.CommClause:
		t.translateStmt(&s.Comm)
		t.translateStmtList(s.Body)
	case *ast.SelectStmt:
		t.translateBlockStmt(s.Body)
	case *ast.ForStmt:
		t.translateStmt(&s.Init)
		t.translateExpr(&s.Cond)
		t.translateStmt(&s.Post)
		t.translateBlockStmt(s.Body)
	case *ast.RangeStmt:
		t.translateExpr(&s.Key)
		t.translateExpr(&s.Value)
		t.translateExpr(&s.X)
		t.translateBlockStmt(s.Body)
	default:
		panic(fmt.Sprintf("unimplemented Stmt %T", s))
	}
}

// translateStmtList translates a list of statements generic Go to Go 1.
func (t *translator) translateStmtList(sl []ast.Stmt) {
	for i := range sl {
		t.translateStmt(&sl[i])
	}
}

// translateExpr translates an expression from generic Go to Go 1.
func (t *translator) translateExpr(pe *ast.Expr) {
	if t.err != nil {
		return
	}
	if *pe == nil {
		return
	}
	switch e := (*pe).(type) {
	case *ast.Ident:
		t.translateIdent(pe)
	case *ast.Ellipsis:
		t.translateExpr(&e.Elt)
	case *ast.BasicLit:
	case *ast.FuncLit:
		t.translateFieldList(e.Type.TParams)
		t.translateFieldList(e.Type.Params)
		t.translateFieldList(e.Type.Results)
		t.translateBlockStmt(e.Body)
	case *ast.CompositeLit:
		t.translateExpr(&e.Type)
		t.translateExprList(e.Elts)
	case *ast.ParenExpr:
		t.translateExpr(&e.X)
	case *ast.SelectorExpr:
		t.translateSelectorExpr(pe)
	case *ast.IndexExpr:
		if ftyp, ok := t.lookupType(e.X).(*types.Signature); ok && len(ftyp.TParams()) > 0 {
			t.translateFunctionInstantiation(pe)
		} else if ntyp, ok := t.lookupType(e.X).(*types.Named); ok && len(ntyp.TParams()) > 0 && len(ntyp.TArgs()) == 0 {
			t.translateTypeInstantiation(pe)
		}
		t.translateExpr(&e.X)
		t.translateExpr(&e.Index)
	case *ast.SliceExpr:
		t.translateExpr(&e.X)
		t.translateExpr(&e.Low)
		t.translateExpr(&e.High)
		t.translateExpr(&e.Max)
	case *ast.TypeAssertExpr:
		t.translateExpr(&e.X)
		t.translateExpr(&e.Type)
	case *ast.CallExpr:
		if ftyp, ok := t.lookupType(e.Fun).(*types.Signature); ok && len(ftyp.TParams()) > 0 {
			t.translateFunctionInstantiation(pe)
		}
		t.translateExprList(e.Args)
		t.translateExpr(&e.Fun)
	case *ast.ListExpr:
		t.translateExprList(e.ElemList)
	case *ast.StarExpr:
		t.translateExpr(&e.X)
	case *ast.UnaryExpr:
		t.translateExpr(&e.X)
	case *ast.BinaryExpr:
		t.translateExpr(&e.X)
		t.translateExpr(&e.Y)
	case *ast.KeyValueExpr:
		t.translateExpr(&e.Key)
		t.translateExpr(&e.Value)
	case *ast.ArrayType:
		t.translateExpr(&e.Len)
		t.translateExpr(&e.Elt)
	case *ast.StructType:
		t.translateFieldList(e.Fields)
	case *ast.FuncType:
		t.translateFieldList(e.TParams)
		t.translateFieldList(e.Params)
		t.translateFieldList(e.Results)
	case *ast.InterfaceType:
		methods, types := splitFieldList(e.Methods)
		t.translateFieldList(methods)
		t.translateExprList(types)
	case *ast.MapType:
		t.translateExpr(&e.Key)
		t.translateExpr(&e.Value)
	case *ast.ChanType:
		t.translateExpr(&e.Value)
	default:
		panic(fmt.Sprintf("unimplemented Expr %T", e))
	}
}

// translateIdent translates a simple identifier generic Go to Go 1.
// These are usually fine as is, but a reference
// to a non-generic name in another package may need a package qualifier.
func (t *translator) translateIdent(pe *ast.Expr) {
	e := (*pe).(*ast.Ident)
	obj := t.importer.info.ObjectOf(e)
	if obj == nil {
		return
	}
	if named, ok := obj.Type().(*types.Named); ok && len(named.TParams()) > 0 {
		// A generic function that will be instantiated locally.
		return
	}
	ipkg := obj.Pkg()
	if ipkg == nil || ipkg == t.tpkg {
		// We don't need a package qualifier if it's defined
		// in the current package.
		return
	}
	if obj.Parent() != ipkg.Scope() {
		// We only need a package qualifier if it's defined in
		// package scope.
		return
	}

	// Add package qualifier.
	*pe = &ast.SelectorExpr{
		X:   ast.NewIdent(ipkg.Name()),
		Sel: e,
	}
}

// translateSelectorExpr translates a selector expression
// from generic Go to Go 1.
func (t *translator) translateSelectorExpr(pe *ast.Expr) {
	e := (*pe).(*ast.SelectorExpr)

	t.translateExpr(&e.X)

	obj := t.importer.info.ObjectOf(e.Sel)
	if obj == nil {
		return
	}

	// Handle references to promoted fields and methods,
	// if they go through an embedded instantiated field.
	// We have to add a reference to the field we inserted.
	if xType := t.lookupType(e.X); xType != nil {
		if ptr := types.AsPointer(xType); ptr != nil {
			xType = ptr.Elem()
		}
		fobj, indexes, _ := types.LookupFieldOrMethod(xType, true, obj.Pkg(), obj.Name())
		if fobj != nil && len(indexes) > 1 {
			for _, index := range indexes[:len(indexes)-1] {
				xf := types.AsStruct(xType).Field(index)
				// This must be an embedded type.
				// If the field name is the one we expect,
				// don't mention it explicitly,
				// because it might not be exported.
				if xf.Name() == types.TypeString(xf.Type(), relativeTo(xf.Pkg())) {
					continue
				}
				e.X = &ast.SelectorExpr{
					X:   e.X,
					Sel: ast.NewIdent(xf.Name()),
				}
				xType = xf.Type()
				if ptr := types.AsPointer(xType); ptr != nil {
					xType = ptr.Elem()
				}
			}
		}
	}

	// Handle references to instantiated embedded fields.
	// We have to rewrite the name to the name used in
	// the translated struct definition.
	if f, ok := obj.(*types.Var); ok && f.Embedded() {
		typ := t.lookupType(e)
		if typ == nil {
			typ = f.Type()
		}
		if pt := types.AsPointer(typ); pt != nil {
			typ = pt.Elem()
		}
		named, ok := typ.(*types.Named)
		if !ok || len(named.TArgs()) == 0 {
			return
		}
		if obj.Name() != named.Obj().Name() {
			return
		}
		_, id := t.lookupInstantiatedType(named)
		*pe = &ast.SelectorExpr{
			X:   e.X,
			Sel: id,
		}
	}
}

// TODO(iant) refactor code and get rid of this?
func splitFieldList(fl *ast.FieldList) (methods *ast.FieldList, types []ast.Expr) {
	if fl == nil {
		return
	}
	var mfields []*ast.Field
	for _, f := range fl.List {
		if len(f.Names) > 0 && f.Names[0].Name == "type" {
			// type list type
			types = append(types, f.Type)
		} else {
			mfields = append(mfields, f)
		}
	}
	copy := *fl
	copy.List = mfields
	methods = &copy
	return
}

// TODO(iant) refactor code and get rid of this?
func mergeFieldList(methods *ast.FieldList, types []ast.Expr) (fl *ast.FieldList) {
	fl = methods
	if len(types) == 0 {
		return
	}
	if fl == nil {
		fl = new(ast.FieldList)
	}
	name := []*ast.Ident{ast.NewIdent("type")}
	for _, typ := range types {
		fl.List = append(fl.List, &ast.Field{Names: name, Type: typ})
	}
	return
}

// translateExprList translate an expression list generic Go to Go 1.
func (t *translator) translateExprList(el []ast.Expr) {
	for i := range el {
		t.translateExpr(&el[i])
	}
}

// translateFieldList translates a field list generic Go to Go 1.
func (t *translator) translateFieldList(fl *ast.FieldList) {
	if fl == nil {
		return
	}
	for _, f := range fl.List {
		t.translateField(f)
	}
}

// translateField translates a field generic Go to Go 1.
func (t *translator) translateField(f *ast.Field) {
	t.translateExpr(&f.Type)
}

// translateFunctionInstantiation translates an instantiated function
// to Go 1.
func (t *translator) translateFunctionInstantiation(pe *ast.Expr) {
	expr := *pe
	qid := t.instantiatedIdent(expr)
	argList, typeList, typeArgs := t.instantiationTypes(expr)
	if t.err != nil {
		return
	}

	var instIdent *ast.Ident
	key := qid.String()
	insts := t.funcInstantiations(key)
	for _, inst := range insts {
		if t.sameTypes(typeList, inst.types) {
			instIdent = inst.decl
			break
		}
	}

	if instIdent == nil {
		var err error
		instIdent, err = t.instantiateFunction(qid, argList, typeList)
		if err != nil {
			t.err = err
			return
		}

		n := &funcInstantiation{
			types: typeList,
			decl:  instIdent,
		}
		t.addFuncInstantiation(key, n)
	}

	if typeArgs {
		*pe = instIdent
	} else {
		switch e := expr.(type) {
		case *ast.CallExpr:
			newCall := *e
			newCall.Fun = instIdent
			*pe = &newCall
		case *ast.IndexExpr:
			*pe = instIdent
		default:
			panic("unexpected AST type")
		}
	}
}

// translateTypeInstantiation translates an instantiated type to Go 1.
func (t *translator) translateTypeInstantiation(pe *ast.Expr) {
	expr := *pe
	qid := t.instantiatedIdent(expr)
	typ := t.lookupType(qid.ident).(*types.Named)
	argList, typeList, typeArgs := t.instantiationTypes(expr)
	if t.err != nil {
		return
	}
	if !typeArgs {
		panic("no type arguments for type")
	}

	var seen *typeInstantiation
	key := t.typeWithoutArgs(typ)
	for _, inst := range t.typeInstantiations(key) {
		if t.sameTypes(typeList, inst.types) {
			if inst.inProgress {
				panic(fmt.Sprintf("%s: circular type instantiation", t.fset.Position((*pe).Pos())))
			}
			if inst.decl == nil {
				// This can happen if we've instantiated
				// the type in instantiateType.
				seen = inst
				break
			}
			*pe = inst.decl
			return
		}
	}

	name, err := t.instantiatedName(qid, typeList)
	if err != nil {
		t.err = err
		return
	}
	instIdent := ast.NewIdent(name)

	if seen != nil {
		seen.decl = instIdent
		seen.inProgress = true
	} else {
		seen = &typeInstantiation{
			types:      typeList,
			decl:       instIdent,
			typ:        nil,
			inProgress: true,
		}
		t.addTypeInstantiation(key, seen)
	}

	defer func() {
		seen.inProgress = false
	}()

	instType, err := t.instantiateTypeDecl(qid, typ, argList, typeList, instIdent)
	if err != nil {
		t.err = err
		return
	}

	if seen.typ == nil {
		seen.typ = instType
	}

	*pe = instIdent
}

// instantiatedIdent returns the qualified identifer that is being
// instantiated.
func (t *translator) instantiatedIdent(x ast.Expr) qualifiedIdent {
	var fun ast.Expr
	switch x := x.(type) {
	case *ast.CallExpr:
		fun = x.Fun
	case *ast.IndexExpr:
		fun = x.X
	default:
		panic(fmt.Sprintf("unexpected AST %T", x))
	}

	switch fun := fun.(type) {
	case *ast.Ident:
		if obj := t.importer.info.ObjectOf(fun); obj != nil && obj.Pkg() != t.tpkg {
			return qualifiedIdent{pkg: obj.Pkg(), ident: fun}
		}
		return qualifiedIdent{ident: fun}
	case *ast.SelectorExpr:
		pkgname, ok := fun.X.(*ast.Ident)
		if !ok {
			break
		}
		pkgobj, ok := t.importer.info.Uses[pkgname]
		if !ok {
			break
		}
		pn, ok := pkgobj.(*types.PkgName)
		if !ok {
			break
		}
		return qualifiedIdent{pkg: pn.Imported(), ident: fun.Sel}
	}
	panic(fmt.Sprintf("instantiated object %T %v is not an identifier", fun, fun))
}

// instantiationTypes returns the type arguments of an instantiation.
// It also returns the AST arguments if they are present.
// The typeArgs result reports whether the AST arguments are types.
func (t *translator) instantiationTypes(x ast.Expr) (argList []ast.Expr, typeList []types.Type, typeArgs bool) {
	var args []ast.Expr
	switch x := x.(type) {
	case *ast.CallExpr:
		// CallExprs may result in an implicit instantiation via type inference.
	case *ast.IndexExpr:
		args = unpackExpr(x.Index)
	default:
		panic(fmt.Sprintf("unexpected AST type %T", x))
	}
	inferredInfo := types.GetInferred(t.importer.info)
	inferred, haveInferred := inferredInfo[x]

	if !haveInferred {
		argList = args
		typeList = make([]types.Type, 0, len(argList))
		for _, arg := range argList {
			if id, ok := arg.(*ast.Ident); ok && id.Name == "_" {
				t.err = fmt.Errorf("%s: go2go tool does not support using _ here", t.fset.Position(arg.Pos()))
				return
			}
			if at := t.lookupType(arg); at == nil {
				panic(fmt.Sprintf("%s: no type found for %T %v", t.fset.Position(arg.Pos()), arg, arg))
			} else {
				typeList = append(typeList, at)
			}
		}
		typeArgs = true
	} else {
		typeList, argList = t.typeListToASTList(inferred.Targs)
	}

	// Instantiating with a locally defined type won't work.
	// Check that here.
	for _, typ := range typeList {
		if named, ok := typ.(*types.Named); ok && named.Obj().Pkg() != nil {
			if scope := named.Obj().Parent(); scope != nil && scope != named.Obj().Pkg().Scope() {
				t.err = fmt.Errorf("%s: go2go tool does not support using locally defined type as type argument", t.fset.Position(x.Pos()))
				return
			}
		}
	}

	return
}

// unpackExpr unpacks an *ast.ListExpr into a list of ast.Expr.
func unpackExpr(x ast.Expr) []ast.Expr {
	if x, _ := x.(*ast.ListExpr); x != nil {
		return x.ElemList
	}
	if x != nil {
		return []ast.Expr{x}
	}
	return nil
}

// lookupInstantiatedType looks for an existing instantiation of an
// instantiated type.
func (t *translator) lookupInstantiatedType(typ *types.Named) (types.Type, *ast.Ident) {
	copyType := func(typ *types.Named, newName string) types.Type {
		nm := typ.NumMethods()
		methods := make([]*types.Func, 0, nm)
		for i := 0; i < nm; i++ {
			methods = append(methods, typ.Method(i))
		}
		obj := typ.Obj()
		obj = types.NewTypeName(obj.Pos(), obj.Pkg(), newName, nil)
		nt := types.NewNamed(obj, typ.Underlying(), methods)
		nt.SetTArgs(typ.TArgs())
		return nt
	}

	targs := typ.TArgs()
	key := t.typeWithoutArgs(typ)
	var seen *typeInstantiation
	for _, inst := range t.typeInstantiations(key) {
		if t.sameTypes(targs, inst.types) {
			if inst.inProgress {
				panic(fmt.Sprintf("instantiation for %v in progress", typ))
			}
			if inst.decl == nil {
				// This can happen if we've instantiated
				// the type in instantiateType.
				seen = inst
				break
			}
			if inst.typ == nil {
				panic(fmt.Sprintf("no type for instantiation entry for %v", typ))
			}
			if instNamed, ok := inst.typ.(*types.Named); ok {
				return copyType(instNamed, inst.decl.Name), inst.decl
			}
			return inst.typ, inst.decl
		}
	}

	typeList, argList := t.typeListToASTList(targs)

	qid := qualifiedIdent{ident: ast.NewIdent(typ.Obj().Name())}
	if typPkg := typ.Obj().Pkg(); typPkg != t.tpkg {
		qid.pkg = typPkg
	}

	name, err := t.instantiatedName(qid, typeList)
	if err != nil {
		t.err = err
		return nil, nil
	}
	instIdent := ast.NewIdent(name)

	if seen != nil {
		seen.decl = instIdent
		seen.inProgress = true
	} else {
		seen = &typeInstantiation{
			types:      targs,
			decl:       instIdent,
			typ:        nil,
			inProgress: true,
		}
		t.addTypeInstantiation(key, seen)
	}

	defer func() {
		seen.inProgress = false
	}()

	instType, err := t.instantiateTypeDecl(qid, typ, argList, typeList, instIdent)
	if err != nil {
		t.err = err
		return nil, nil
	}

	if seen.typ == nil {
		seen.typ = instType
	} else {
		instType = seen.typ
	}

	if instNamed, ok := instType.(*types.Named); ok {
		return copyType(instNamed, instIdent.Name), instIdent
	}
	return instType, instIdent
}

// typeWithoutArgs takes a named type with arguments and returns the
// same type without arguments.
func (t *translator) typeWithoutArgs(typ *types.Named) *types.Named {
	if len(typ.TArgs()) == 0 {
		return typ
	}
	name := typ.Obj().Name()
	fields := strings.Split(name, ".")
	if len(fields) > 2 {
		panic(fmt.Sprintf("unparseable instantiated name %q", name))
	}
	if len(fields) > 1 {
		name = fields[1]
	}

	tpkg := typ.Obj().Pkg()
	if tpkg == nil {
		panic(fmt.Sprintf("can't find package for %s", name))
	}
	nobj := tpkg.Scope().Lookup(name)
	if nobj == nil {
		panic(fmt.Sprintf("can't find %q in scope of package %q", name, tpkg.Name()))
	}
	return nobj.Type().(*types.Named)
}

// typeListToASTList returns an AST list for a type list,
// as well as an updated type list.
func (t *translator) typeListToASTList(typeList []types.Type) ([]types.Type, []ast.Expr) {
	argList := make([]ast.Expr, 0, len(typeList))
	for _, typ := range typeList {
		argList = append(argList, t.typeToAST(typ))

		// This inferred type may introduce a reference to
		// packages that we don't otherwise import, and that
		// package name may wind up in arg. Record all packages
		// seen in inferred types so that we add import
		// statements for them, just in case.
		t.addTypePackages(typ)
	}
	return typeList, argList
}

// relativeTo is like types.RelativeTo, but returns just the package name,
// not the package path.
func relativeTo(pkg *types.Package) types.Qualifier {
	return func(other *types.Package) string {
		if pkg == other {
			return "" // same package; unqualified
		}
		return other.Name()
	}
}

// sameTypes reports whether two type slices are the same.
func (t *translator) sameTypes(a, b []types.Type) bool {
	if len(a) != len(b) {
		return false
	}
	for i, x := range a {
		if !t.sameType(x, b[i]) {
			return false
		}
	}
	return true
}

// sameType reports whether two types are the same.
// We have to check type arguments ourselves.
func (t *translator) sameType(a, b types.Type) bool {
	if types.IdenticalIgnoreTags(a, b) {
		return true
	}
	if ap, bp := types.AsPointer(a), types.AsPointer(b); ap != nil && bp != nil {
		a = ap.Elem()
		b = bp.Elem()
	}
	an, ok := a.(*types.Named)
	if !ok {
		return false
	}
	bn, ok := b.(*types.Named)
	if !ok {
		return false
	}
	if an.Obj().Name() != bn.Obj().Name() {
		return false
	}
	if len(an.TArgs()) == 0 || len(an.TArgs()) != len(bn.TArgs()) {
		return false
	}
	for i, typ := range an.TArgs() {
		if !t.sameType(typ, bn.TArgs()[i]) {
			return false
		}
	}
	return true
}

// qualifiedIdent is an identifier possibly qualified with a package.
type qualifiedIdent struct {
	pkg   *types.Package // identifier's package; nil for current package
	ident *ast.Ident
}

// String returns a printable name for qid.
func (qid qualifiedIdent) String() string {
	if qid.pkg == nil {
		return qid.ident.Name
	}
	return qid.pkg.Path() + "." + qid.ident.Name
}
