// 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"
	"sort"
	"strings"
	"sync"
	"time"

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

// KnownPackages returns a list of all known packages
// in the package graph that could potentially be imported
// by the given file.
func KnownPackages(ctx context.Context, snapshot Snapshot, fh VersionedFileHandle) ([]string, error) {
	pkg, pgf, err := GetParsedFile(ctx, snapshot, fh, NarrowestPackage)
	if err != nil {
		return nil, fmt.Errorf("GetParsedFile: %w", err)
	}
	alreadyImported := map[string]struct{}{}
	for _, imp := range pgf.File.Imports {
		alreadyImported[imp.Path.Value] = struct{}{}
	}
	pkgs, err := snapshot.CachedImportPaths(ctx)
	if err != nil {
		return nil, err
	}
	var (
		seen  = make(map[string]struct{})
		paths []string
	)
	for path, knownPkg := range pkgs {
		gofiles := knownPkg.CompiledGoFiles()
		if len(gofiles) == 0 || gofiles[0].File.Name == nil {
			continue
		}
		pkgName := gofiles[0].File.Name.Name
		// package main cannot be imported
		if pkgName == "main" {
			continue
		}
		// test packages cannot be imported
		if knownPkg.ForTest() != "" {
			continue
		}
		// no need to import what the file already imports
		if _, ok := alreadyImported[path]; ok {
			continue
		}
		// snapshot.KnownPackages could have multiple versions of a pkg
		if _, ok := seen[path]; ok {
			continue
		}
		seen[path] = struct{}{}
		// make sure internal packages are importable by the file
		if !IsValidImport(pkg.PkgPath(), path) {
			continue
		}
		// naive check on cyclical imports
		if isDirectlyCyclical(pkg, knownPkg) {
			continue
		}
		paths = append(paths, path)
		seen[path] = struct{}{}
	}
	err = snapshot.RunProcessEnvFunc(ctx, func(o *imports.Options) error {
		var mu sync.Mutex
		ctx, cancel := context.WithTimeout(ctx, time.Millisecond*80)
		defer cancel()
		return imports.GetAllCandidates(ctx, func(ifix imports.ImportFix) {
			mu.Lock()
			defer mu.Unlock()
			if _, ok := seen[ifix.StmtInfo.ImportPath]; ok {
				return
			}
			paths = append(paths, ifix.StmtInfo.ImportPath)
		}, "", pgf.URI.Filename(), pkg.GetTypes().Name(), o.Env)
	})
	if err != nil {
		// if an error occurred, we still have a decent list we can
		// show to the user through snapshot.CachedImportPaths
		event.Error(ctx, "imports.GetAllCandidates", err)
	}
	sort.Slice(paths, func(i, j int) bool {
		importI, importJ := paths[i], paths[j]
		iHasDot := strings.Contains(importI, ".")
		jHasDot := strings.Contains(importJ, ".")
		if iHasDot && !jHasDot {
			return false
		}
		if jHasDot && !iHasDot {
			return true
		}
		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.
func isDirectlyCyclical(pkg, imported Package) bool {
	for _, imp := range imported.Imports() {
		if imp.PkgPath() == pkg.PkgPath() {
			return true
		}
	}
	return false
}
