// 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 source

import (
	"context"
	"fmt"
	"go/parser"
	"go/token"
	"sort"
	"strings"
	"sync"
	"time"

	"golang.org/x/tools/internal/event"
	"golang.org/x/tools/internal/imports"
)

// KnownPackagePaths returns a new list of package paths of all known
// packages in the package graph that could potentially be imported by
// the given file. The list is ordered lexicographically, except that
// all dot-free paths (standard packages) appear before dotful ones.
//
// It is part of the gopls.list_known_packages command.
func KnownPackagePaths(ctx context.Context, snapshot Snapshot, fh FileHandle) ([]PackagePath, error) {
	// This algorithm is expressed in terms of Metadata, not Packages,
	// so it doesn't cause or wait for type checking.

	// Find a Metadata containing the file.
	metas, err := snapshot.MetadataForFile(ctx, fh.URI())
	if err != nil {
		return nil, err // e.g. context cancelled
	}
	if len(metas) == 0 {
		return nil, fmt.Errorf("no loaded package contain file %s", fh.URI())
	}
	current := metas[0] // pick one arbitrarily (they should all have the same package path)

	// Parse the file's imports so we can compute which
	// PackagePaths are imported by this specific file.
	src, err := fh.Read()
	if err != nil {
		return nil, err
	}
	file, err := parser.ParseFile(token.NewFileSet(), fh.URI().Filename(), src, parser.ImportsOnly)
	if err != nil {
		return nil, err
	}
	imported := make(map[PackagePath]bool)
	for _, imp := range file.Imports {
		if id := current.DepsByImpPath[UnquoteImportPath(imp)]; id != "" {
			if m := snapshot.Metadata(id); m != nil {
				imported[m.PkgPath] = true
			}
		}
	}

	// Now find candidates among known packages.
	knownPkgs, err := snapshot.AllMetadata(ctx)
	if err != nil {
		return nil, err
	}
	seen := make(map[PackagePath]bool)
	for _, knownPkg := range knownPkgs {
		// package main cannot be imported
		if knownPkg.Name == "main" {
			continue
		}
		// test packages cannot be imported
		if knownPkg.ForTest != "" {
			continue
		}
		// No need to import what the file already imports.
		// This check is based on PackagePath, not PackageID,
		// so that all test variants are filtered out too.
		if imported[knownPkg.PkgPath] {
			continue
		}
		// make sure internal packages are importable by the file
		if !IsValidImport(current.PkgPath, knownPkg.PkgPath) {
			continue
		}
		// naive check on cyclical imports
		if isDirectlyCyclical(current, knownPkg) {
			continue
		}
		// AllMetadata may have multiple variants of a pkg.
		seen[knownPkg.PkgPath] = true
	}

	// Augment the set by invoking the goimports algorithm.
	if err := snapshot.RunProcessEnvFunc(ctx, func(o *imports.Options) error {
		ctx, cancel := context.WithTimeout(ctx, time.Millisecond*80)
		defer cancel()
		var seenMu sync.Mutex
		wrapped := func(ifix imports.ImportFix) {
			seenMu.Lock()
			defer seenMu.Unlock()
			// TODO(adonovan): what if the actual package path has a vendor/ prefix?
			seen[PackagePath(ifix.StmtInfo.ImportPath)] = true
		}
		return imports.GetAllCandidates(ctx, wrapped, "", fh.URI().Filename(), string(current.Name), o.Env)
	}); err != nil {
		// If goimports failed, proceed with just the candidates from the metadata.
		event.Error(ctx, "imports.GetAllCandidates", err)
	}

	// Sort lexicographically, but with std before non-std packages.
	paths := make([]PackagePath, 0, len(seen))
	for path := range seen {
		paths = append(paths, path)
	}
	sort.Slice(paths, func(i, j int) bool {
		importI, importJ := paths[i], paths[j]
		iHasDot := strings.Contains(string(importI), ".")
		jHasDot := strings.Contains(string(importJ), ".")
		if iHasDot != jHasDot {
			return jHasDot // dot-free paths (standard packages) compare less
		}
		return importI < importJ
	})

	return paths, nil
}

// isDirectlyCyclical checks if imported directly imports pkg.
// It does not (yet) offer a full cyclical check because showing a user
// a list of importable packages already generates a very large list
// and having a few false positives in there could be worth the
// performance snappiness.
//
// TODO(adonovan): ensure that metadata graph is always cyclic!
// Many algorithms will get confused or even stuck in the
// presence of cycles. Then replace this function by 'false'.
func isDirectlyCyclical(pkg, imported *Metadata) bool {
	_, ok := imported.DepsByPkgPath[pkg.PkgPath]
	return ok
}
