// Copyright 2025 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 completion

// unimported completion is invoked when the user types something like 'foo.xx',
// foo is known to be a package name not yet imported in the current file, and
// xx (or whatever the user has typed) is interpreted as a hint (pattern) for the
// member of foo that the user is looking for.
//
// This code looks for a suitable completion in a number of places. A 'suitable
// completion' is an exported symbol (so a type, const, var, or func) from package
// foo, which, after converting everything to lower case, has the pattern as a
// subsequence.
//
// The code looks for a suitable completion in
// 1. the imports of some other file of the current package,
// 2. the standard library,
// 3. the imports of some other file in the current workspace,
// 4. the module cache.
// It stops at the first success.

import (
	"context"
	"fmt"
	"go/ast"
	"go/printer"
	"go/token"
	"path"
	"slices"
	"strings"

	"golang.org/x/tools/gopls/internal/cache/metadata"
	"golang.org/x/tools/gopls/internal/golang/completion/snippet"
	"golang.org/x/tools/gopls/internal/protocol"
	"golang.org/x/tools/gopls/internal/util/bug"
	"golang.org/x/tools/internal/imports"
	"golang.org/x/tools/internal/modindex"
	"golang.org/x/tools/internal/stdlib"
	"golang.org/x/tools/internal/versions"
)

func (c *completer) unimported(ctx context.Context, pkgname metadata.PackageName, prefix string) {
	wsIDs, ourIDs := c.findPackageIDs(pkgname)
	stdpkgs := c.stdlibPkgs(pkgname)
	if len(ourIDs) > 0 {
		// use the one in the current package, if possible
		items := c.pkgIDmatches(ctx, ourIDs, pkgname, prefix)
		if c.scoreList(items) {
			return
		}
	}
	// do the stdlib next.
	items := c.stdlibMatches(stdpkgs, pkgname, prefix)
	if c.scoreList(items) {
		return
	}

	// look in the rest of the workspace
	items = c.pkgIDmatches(ctx, wsIDs, pkgname, prefix)
	if c.scoreList(items) {
		return
	}

	// look in the module cache, for the last chance
	items, err := c.modcacheMatches(pkgname, prefix)
	if err == nil {
		c.scoreList(items)
	}
}

// find all the packageIDs for packages in the workspace that have the desired name
// thisPkgIDs contains the ones known to the current package, wsIDs contains the others
func (c *completer) findPackageIDs(pkgname metadata.PackageName) (wsIDs, thisPkgIDs []metadata.PackageID) {
	g := c.snapshot.MetadataGraph()
	for pid, pkg := range c.snapshot.MetadataGraph().Packages {
		if pkg.Name != pkgname {
			continue
		}
		imports := g.ImportedBy[pid]
		// Metadata is not canonical: it may be held onto by a package. Therefore,
		// we must compare by ID.
		thisPkg := func(mp *metadata.Package) bool { return mp.ID == c.pkg.Metadata().ID }
		if slices.ContainsFunc(imports, thisPkg) {
			thisPkgIDs = append(thisPkgIDs, pid)
		} else {
			wsIDs = append(wsIDs, pid)
		}
	}
	return
}

// find all the stdlib packages that have the desired name
func (c *completer) stdlibPkgs(pkgname metadata.PackageName) []metadata.PackagePath {
	var pkgs []metadata.PackagePath // stlib packages that match pkg
	for pkgpath := range stdlib.PackageSymbols {
		v := metadata.PackageName(path.Base(pkgpath))
		if v == pkgname {
			pkgs = append(pkgs, metadata.PackagePath(pkgpath))
		} else if imports.WithoutVersion(string(pkgpath)) == string(pkgname) {
			pkgs = append(pkgs, metadata.PackagePath(pkgpath))
		}
	}
	return pkgs
}

// return CompletionItems for all matching symbols in the packages in ids.
func (c *completer) pkgIDmatches(ctx context.Context, ids []metadata.PackageID, pkgname metadata.PackageName, prefix string) []CompletionItem {
	pattern := strings.ToLower(prefix)
	allpkgsyms, err := c.snapshot.Symbols(ctx, ids...)
	if err != nil {
		return nil // would if be worth retrying the ids one by one?
	}
	if len(allpkgsyms) != len(ids) {
		bug.Reportf("Symbols returned %d values for %d pkgIDs", len(allpkgsyms), len(ids))
		return nil
	}
	var got []CompletionItem
	for i, pkgID := range ids {
		pkg := c.snapshot.MetadataGraph().Packages[pkgID]
		if pkg == nil {
			bug.Reportf("no metadata for %s", pkgID)
			continue // something changed underfoot, otherwise can't happen
		}
		pkgsyms := allpkgsyms[i]
		pkgfname := pkgsyms.Files[0].Path()
		if !imports.CanUse(c.filename, pkgfname) {
			// avoid unusable internal, etc
			continue
		}
		// are any of these any good?
		for np, asym := range pkgsyms.Symbols {
			for _, sym := range asym {
				if !token.IsExported(sym.Name) {
					continue
				}
				if !usefulCompletion(sym.Name, pattern) {
					// for json.U, the existing code finds InvalidUTF8Error
					continue
				}
				var params []string
				var kind protocol.CompletionItemKind
				var detail string
				switch sym.Kind {
				case protocol.Function:
					foundURI := pkgsyms.Files[np]
					fh := c.snapshot.FindFile(foundURI)
					pgf, err := c.snapshot.ParseGo(ctx, fh, 0)
					if err == nil {
						params = funcParams(pgf.File, sym.Name)
					}
					kind = protocol.FunctionCompletion
					detail = fmt.Sprintf("func (from %q)", pkg.PkgPath)
				case protocol.Variable, protocol.Struct:
					kind = protocol.VariableCompletion
					detail = fmt.Sprintf("var (from %q)", pkg.PkgPath)
				case protocol.Constant:
					kind = protocol.ConstantCompletion
					detail = fmt.Sprintf("const (from %q)", pkg.PkgPath)
				default:
					continue
				}
				got = c.appendNewItem(got, sym.Name,
					detail,
					pkg.PkgPath,
					kind,
					pkgname, params)
			}
		}
	}
	return got
}

// return CompletionItems for all the matches in packages in pkgs.
func (c *completer) stdlibMatches(pkgs []metadata.PackagePath, pkg metadata.PackageName, prefix string) []CompletionItem {
	// check for deprecated symbols someday
	got := make([]CompletionItem, 0)
	pattern := strings.ToLower(prefix)
	// avoid non-determinacy, especially for marker tests
	slices.Sort(pkgs)
	for _, candpkg := range pkgs {
		if std, ok := stdlib.PackageSymbols[string(candpkg)]; ok {
			for _, sym := range std {
				if !usefulCompletion(sym.Name, pattern) {
					continue
				}
				if !versions.AtLeast(c.goversion, sym.Version.String()) {
					continue
				}
				var kind protocol.CompletionItemKind
				var detail string
				var params []string
				switch sym.Kind {
				case stdlib.Func:
					params = parseSignature(sym.Signature)
					kind = protocol.FunctionCompletion
					detail = fmt.Sprintf("func (from %q)", candpkg)
				case stdlib.Const:
					kind = protocol.ConstantCompletion
					detail = fmt.Sprintf("const (from %q)", candpkg)
				case stdlib.Var:
					kind = protocol.VariableCompletion
					detail = fmt.Sprintf("var (from %q)", candpkg)
				case stdlib.Type:
					kind = protocol.VariableCompletion
					detail = fmt.Sprintf("type (from %q)", candpkg)
				default:
					continue
				}
				got = c.appendNewItem(got, sym.Name,
					detail,
					candpkg,
					kind,
					pkg, params)
			}
		}
	}
	return got
}

func (c *completer) modcacheMatches(pkg metadata.PackageName, prefix string) ([]CompletionItem, error) {
	ix, err := c.snapshot.View().ModcacheIndex()
	if err != nil {
		return nil, err
	}
	// retrieve everything and let usefulCompletion() and the matcher sort them out
	cands := ix.Lookup(string(pkg), "", true)
	lx := len(cands)
	got := make([]CompletionItem, 0, lx)
	pattern := strings.ToLower(prefix)
	for _, cand := range cands {
		if !usefulCompletion(cand.Name, pattern) {
			continue
		}
		var params []string
		var kind protocol.CompletionItemKind
		var detail string
		switch cand.Type {
		case modindex.Func:
			for _, f := range cand.Sig {
				params = append(params, fmt.Sprintf("%s %s", f.Arg, f.Type))
			}
			kind = protocol.FunctionCompletion
			detail = fmt.Sprintf("func (from %s)", cand.ImportPath)
		case modindex.Var:
			kind = protocol.VariableCompletion
			detail = fmt.Sprintf("var (from %s)", cand.ImportPath)
		case modindex.Const:
			kind = protocol.ConstantCompletion
			detail = fmt.Sprintf("const (from %s)", cand.ImportPath)
		case modindex.Type: // might be a type alias
			kind = protocol.VariableCompletion
			detail = fmt.Sprintf("type (from %s)", cand.ImportPath)
		default:
			continue
		}
		got = c.appendNewItem(got, cand.Name,
			detail,
			metadata.PackagePath(cand.ImportPath),
			kind,
			pkg, params)
	}
	return got, nil
}

func (c *completer) appendNewItem(got []CompletionItem, name, detail string, path metadata.PackagePath, kind protocol.CompletionItemKind, pkg metadata.PackageName, params []string) []CompletionItem {
	item := CompletionItem{
		Label:      name,
		Detail:     detail,
		InsertText: name,
		Kind:       kind,
	}
	imp := importInfo{
		importPath: string(path),
		name:       string(pkg),
	}
	if imports.ImportPathToAssumedName(string(path)) == string(pkg) {
		imp.name = ""
	}
	item.AdditionalTextEdits, _ = c.importEdits(&imp)
	if params != nil {
		var sn snippet.Builder
		c.functionCallSnippet(name, nil, params, &sn)
		item.snippet = &sn
	}
	got = append(got, item)
	return got
}

// score the list. Return true if any item is added to c.items
func (c *completer) scoreList(items []CompletionItem) bool {
	ret := false
	for _, item := range items {
		item.Score = float64(c.matcher.Score(item.Label))
		if item.Score > 0 {
			c.items = append(c.items, item)
			ret = true
		}
	}
	return ret
}

// pattern is always the result of strings.ToLower
func usefulCompletion(name, pattern string) bool {
	// this travesty comes from foo.(type) somehow. see issue59096.txt
	if pattern == "_" {
		return true
	}
	// convert both to lower case, and then the runes in the pattern have to occur, in order,
	// in the name
	cand := strings.ToLower(name)
	for _, r := range pattern {
		ix := strings.IndexRune(cand, r)
		if ix < 0 {
			return false
		}
		cand = cand[ix+1:]
	}
	return true
}

// return a printed version of the function arguments for snippets
func funcParams(f *ast.File, fname string) []string {
	var params []string
	setParams := func(list *ast.FieldList) {
		if list == nil {
			return
		}
		var cfg printer.Config // slight overkill
		param := func(name string, typ ast.Expr) {
			var buf strings.Builder
			buf.WriteString(name)
			buf.WriteByte(' ')
			cfg.Fprint(&buf, token.NewFileSet(), typ) // ignore error
			params = append(params, buf.String())
		}

		for _, field := range list.List {
			if field.Names != nil {
				for _, name := range field.Names {
					param(name.Name, field.Type)
				}
			} else {
				param("_", field.Type)
			}
		}
	}
	for _, n := range f.Decls {
		switch x := n.(type) {
		case *ast.FuncDecl:
			if x.Recv == nil && x.Name.Name == fname {
				setParams(x.Type.Params)
			}
		}
	}
	return params
}

// extract the formal parameters from the signature.
// func[M1 ~map[K]V, M2 ~map[K]V, K comparable, V any](dst M1, src M2) -> []{"dst M1", "src M2"}
// func[K comparable, V any](seq iter.Seq2[K, V]) map[K]V -> []{"seq iter.Seq2[K, V]"}
// func(args ...any) *Logger -> []{"args ...any"}
// func[M ~map[K]V, K comparable, V any](m M, del func(K, V) bool) -> []{"m M", "del func(K, V) bool"}
func parseSignature(sig string) []string {
	var level int       // nesting level of delimiters
	var processing bool // are we doing the params
	var last int        // start of current parameter
	var params []string
	for i := range len(sig) {
		switch sig[i] {
		case '[', '{':
			level++
		case ']', '}':
			level--
		case '(':
			level++
			if level == 1 {
				processing = true
				last = i + 1
			}
		case ')':
			level--
			if level == 0 && processing { // done
				if i > last {
					params = append(params, strings.TrimSpace(sig[last:i]))
				}
				return params
			}
		case ',':
			if level == 1 && processing {
				params = append(params, strings.TrimSpace(sig[last:i]))
				last = i + 1
			}
		}
	}
	return nil
}
