// Copyright 2021 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 noder

import (
	"fmt"
	"internal/buildcfg"
	"internal/types/errors"
	"regexp"
	"sort"

	"cmd/compile/internal/base"
	"cmd/compile/internal/midway"
	"cmd/compile/internal/rangefunc"
	"cmd/compile/internal/syntax"
	"cmd/compile/internal/typecheck"
	"cmd/compile/internal/types"
	"cmd/compile/internal/types2"
	"cmd/internal/src"
)

var versionErrorRx = regexp.MustCompile(`requires go[0-9]+\.[0-9]+ or later`)

// checkFiles configures and runs the types2 checker on the given
// parsed source files and then returns the result.
// The map result value indicates which closures are generated from the bodies of range function loops.
func checkFiles(m posMap, noders []*noder) (*types2.Package, *types2.Info, map[*syntax.FuncLit]bool) {
	if base.SyntaxErrors() != 0 {
		base.ErrorExit()
	}

	// setup and syntax error reporting
	files := make([]*syntax.File, len(noders))
	// fileBaseMap maps all file pos bases back to *syntax.File
	// for checking Go version mismatched.
	fileBaseMap := make(map[*syntax.PosBase]*syntax.File)
	for i, p := range noders {
		files[i] = p.file
		// The file.Pos() is the position of the package clause.
		// If there's a //line directive before that, file.Pos().Base()
		// refers to that directive, not the file itself.
		// Make sure to consistently map back to file base, here and
		// when we look for a file in the conf.Error handler below,
		// otherwise the file may not be found (was go.dev/issue/67141).
		fileBaseMap[p.file.Pos().FileBase()] = p.file
	}

	didMidway := false

recheck:
	// typechecking
	ctxt := types2.NewContext()
	importer := gcimports{
		ctxt:     ctxt,
		packages: make(map[string]*types2.Package),
	}
	conf := types2.Config{
		Context:            ctxt,
		GoVersion:          base.Flag.Lang,
		IgnoreBranchErrors: true, // parser already checked via syntax.CheckBranches mode
		Importer:           &importer,
		Sizes:              types2.SizesFor("gc", buildcfg.GOARCH),
	}
	if base.Flag.ErrorURL {
		conf.ErrorURL = " [go.dev/e/%s]"
	}
	info := &types2.Info{
		StoreTypesInSyntax: true,
		Defs:               make(map[*syntax.Name]types2.Object),
		Uses:               make(map[*syntax.Name]types2.Object),
		Selections:         make(map[*syntax.SelectorExpr]*types2.Selection),
		Implicits:          make(map[syntax.Node]types2.Object),
		Scopes:             make(map[syntax.Node]*types2.Scope),
		Instances:          make(map[*syntax.Name]types2.Instance),
		FileVersions:       make(map[*syntax.PosBase]string),
		// expand as needed
	}
	conf.Error = func(err error) {
		terr := err.(types2.Error)
		msg := terr.Msg
		if versionErrorRx.MatchString(msg) {
			fileBase := terr.Pos.FileBase()
			fileVersion := info.FileVersions[fileBase]
			file := fileBaseMap[fileBase]
			if file == nil {
				// This should never happen, but be careful and don't crash.
			} else if file.GoVersion == fileVersion {
				// If we have a version error caused by //go:build, report it.
				msg = fmt.Sprintf("%s (file declares //go:build %s)", msg, fileVersion)
			} else {
				// Otherwise, hint at the -lang setting.
				msg = fmt.Sprintf("%s (-lang was set to %s; check go.mod)", msg, base.Flag.Lang)
			}
		}
		base.ErrorfAt(m.makeXPos(terr.Pos), terr.Code, "%s", msg)
	}

	pkg, err := conf.Check(base.Ctxt.Pkgpath, files, info)
	base.ExitIfErrors()
	if err != nil {
		base.FatalfAt(src.NoXPos, "conf.Check error: %v", err)
	}

	// Check for anonymous interface cycles (#56103).
	// TODO(gri) move this code into the type checkers (types2 and go/types)
	var f cycleFinder
	for _, file := range files {
		syntax.Inspect(file, func(n syntax.Node) bool {
			if n, ok := n.(*syntax.InterfaceType); ok {
				if f.hasCycle(types2.Unalias(n.GetTypeInfo().Type).(*types2.Interface)) {
					base.ErrorfAt(m.makeXPos(n.Pos()), errors.InvalidTypeCycle, "invalid recursive type: anonymous interface refers to itself (see https://go.dev/issue/56103)")

					for typ := range f.cyclic {
						f.cyclic[typ] = false // suppress duplicate errors
					}
				}
				return false
			}
			return true
		})
	}
	base.ExitIfErrors()

	// Implementation restriction: we don't allow not-in-heap types to
	// be used as type arguments (#54765).
	{
		type nihTarg struct {
			pos src.XPos
			typ types2.Type
		}
		var nihTargs []nihTarg

		for name, inst := range info.Instances {
			for i := 0; i < inst.TypeArgs.Len(); i++ {
				if targ := inst.TypeArgs.At(i); isNotInHeap(targ) {
					nihTargs = append(nihTargs, nihTarg{m.makeXPos(name.Pos()), targ})
				}
			}
		}
		sort.Slice(nihTargs, func(i, j int) bool {
			ti, tj := nihTargs[i], nihTargs[j]
			return ti.pos.Before(tj.pos)
		})
		for _, targ := range nihTargs {
			base.ErrorfAt(targ.pos, 0, "cannot use incomplete (or unallocatable) type as a type argument: %v", targ.typ)
		}
	}
	base.ExitIfErrors()

	// Implementation restriction: we don't allow not-in-heap types to
	// be used as map keys/values, or channel.
	{
		for _, file := range files {
			syntax.Inspect(file, func(n syntax.Node) bool {
				if n, ok := n.(*syntax.TypeDecl); ok {
					switch n := n.Type.(type) {
					case *syntax.MapType:
						typ := n.GetTypeInfo().Type.Underlying().(*types2.Map)
						if isNotInHeap(typ.Key()) {
							base.ErrorfAt(m.makeXPos(n.Pos()), 0, "incomplete (or unallocatable) map key not allowed")
						}
						if isNotInHeap(typ.Elem()) {
							base.ErrorfAt(m.makeXPos(n.Pos()), 0, "incomplete (or unallocatable) map value not allowed")
						}
					case *syntax.ChanType:
						typ := n.GetTypeInfo().Type.Underlying().(*types2.Chan)
						if isNotInHeap(typ.Elem()) {
							base.ErrorfAt(m.makeXPos(n.Pos()), 0, "chan of incomplete (or unallocatable) type not allowed")
						}
					}
				}
				return true
			})
		}
	}
	base.ExitIfErrors()

	if len(base.Debug.AstDump) > 0 {
		dumpSyntax(pkg, info, files, "checked")
	}

	if buildcfg.Experiment.SIMD && !didMidway {
		didMidway = true
		// Perform midway transformation on AST directly
		if midway.RewriteWrapper(pkg, info, files) {
			// midway made changes; type checking must be repeated.
			if len(base.Debug.AstDump) > 0 {
				// TODO how should this interact with -W and textual dumps
				dumpSyntax(pkg, info, files, "midway before recheck")
			}
			// necessary to reset type checking
			for _, p := range types.PkgMap() {
				p.Direct = false
			}
			// necessary to reset type checking
			typecheck.Target.Imports = nil
			goto recheck
		}
	}

	if len(base.Debug.AstDump) > 0 {
		dumpSyntax(pkg, info, files, "midway after recheck")
	}

	// Rewrite range over function to explicit function calls
	// with the loop bodies converted into new implicit closures.
	// We do this now, before serialization to unified IR, so that if the
	// implicit closures are inlined, we will have the unified IR form.
	// If we do the rewrite in the back end, like between typecheck and walk,
	// then the new implicit closure will not have a unified IR inline body,
	// and bodyReaderFor will fail.
	rangeInfo := rangefunc.Rewrite(pkg, info, files)

	if len(base.Debug.AstDump) > 0 {
		dumpSyntax(pkg, info, files, "rangefunc")
	}

	return pkg, info, rangeInfo
}

func dumpSyntax(pkg *types2.Package, info *types2.Info, files []*syntax.File, phase string) {
	for _, file := range files {
		for _, decl := range file.DeclList {
			if fn, ok := decl.(*syntax.FuncDecl); ok {
				if MatchASTDump(fn) {
					DumpNodeHTML(pkg, file, info, fn, phase, fn)
				}
			}
		}
	}
}

// A cycleFinder detects anonymous interface cycles (go.dev/issue/56103).
type cycleFinder struct {
	cyclic map[*types2.Interface]bool
}

// hasCycle reports whether typ is part of an anonymous interface cycle.
func (f *cycleFinder) hasCycle(typ *types2.Interface) bool {
	// We use Method instead of ExplicitMethod to implicitly expand any
	// embedded interfaces. Then we just need to walk any anonymous
	// types, keeping track of *types2.Interface types we visit along
	// the way.
	for i := 0; i < typ.NumMethods(); i++ {
		if f.visit(typ.Method(i).Type()) {
			return true
		}
	}
	return false
}

// visit recursively walks typ0 to check any referenced interface types.
func (f *cycleFinder) visit(typ0 types2.Type) bool {
	for { // loop for tail recursion
		switch typ := types2.Unalias(typ0).(type) {
		default:
			base.Fatalf("unexpected type: %T", typ)

		case *types2.Basic, *types2.Named, *types2.TypeParam:
			return false // named types cannot be part of an anonymous cycle
		case *types2.Pointer:
			typ0 = typ.Elem()
		case *types2.Array:
			typ0 = typ.Elem()
		case *types2.Chan:
			typ0 = typ.Elem()
		case *types2.Map:
			if f.visit(typ.Key()) {
				return true
			}
			typ0 = typ.Elem()
		case *types2.Slice:
			typ0 = typ.Elem()

		case *types2.Struct:
			for i := 0; i < typ.NumFields(); i++ {
				if f.visit(typ.Field(i).Type()) {
					return true
				}
			}
			return false

		case *types2.Interface:
			// The empty interface (e.g., "any") cannot be part of a cycle.
			if typ.NumExplicitMethods() == 0 && typ.NumEmbeddeds() == 0 {
				return false
			}

			// As an optimization, we wait to allocate cyclic here, after
			// we've found at least one other (non-empty) anonymous
			// interface. This means when a cycle is present, we need to
			// make an extra recursive call to actually detect it. But for
			// most packages, it allows skipping the map allocation
			// entirely.
			if x, ok := f.cyclic[typ]; ok {
				return x
			}
			if f.cyclic == nil {
				f.cyclic = make(map[*types2.Interface]bool)
			}
			f.cyclic[typ] = true
			if f.hasCycle(typ) {
				return true
			}
			f.cyclic[typ] = false
			return false

		case *types2.Signature:
			return f.visit(typ.Params()) || f.visit(typ.Results())
		case *types2.Tuple:
			for i := 0; i < typ.Len(); i++ {
				if f.visit(typ.At(i).Type()) {
					return true
				}
			}
			return false
		}
	}
}
