package packages

import (
	"encoding/json"
	"fmt"
	"go/parser"
	"go/token"
	"log"
	"os"
	"path/filepath"
	"regexp"
	"sort"
	"strconv"
	"strings"

	"golang.org/x/tools/internal/gocommand"
)

// processGolistOverlay provides rudimentary support for adding
// files that don't exist on disk to an overlay. The results can be
// sometimes incorrect.
// TODO(matloob): Handle unsupported cases, including the following:
// - determining the correct package to add given a new import path
func (state *golistState) processGolistOverlay(response *responseDeduper) (modifiedPkgs, needPkgs []string, err error) {
	havePkgs := make(map[string]string) // importPath -> non-test package ID
	needPkgsSet := make(map[string]bool)
	modifiedPkgsSet := make(map[string]bool)

	pkgOfDir := make(map[string][]*Package)
	for _, pkg := range response.dr.Packages {
		// This is an approximation of import path to id. This can be
		// wrong for tests, vendored packages, and a number of other cases.
		havePkgs[pkg.PkgPath] = pkg.ID
		x := commonDir(pkg.GoFiles)
		if x != "" {
			pkgOfDir[x] = append(pkgOfDir[x], pkg)
		}
	}

	// If no new imports are added, it is safe to avoid loading any needPkgs.
	// Otherwise, it's hard to tell which package is actually being loaded
	// (due to vendoring) and whether any modified package will show up
	// in the transitive set of dependencies (because new imports are added,
	// potentially modifying the transitive set of dependencies).
	var overlayAddsImports bool

	// If both a package and its test package are created by the overlay, we
	// need the real package first. Process all non-test files before test
	// files, and make the whole process deterministic while we're at it.
	var overlayFiles []string
	for opath := range state.cfg.Overlay {
		overlayFiles = append(overlayFiles, opath)
	}
	sort.Slice(overlayFiles, func(i, j int) bool {
		iTest := strings.HasSuffix(overlayFiles[i], "_test.go")
		jTest := strings.HasSuffix(overlayFiles[j], "_test.go")
		if iTest != jTest {
			return !iTest // non-tests are before tests.
		}
		return overlayFiles[i] < overlayFiles[j]
	})
	for _, opath := range overlayFiles {
		contents := state.cfg.Overlay[opath]
		base := filepath.Base(opath)
		dir := filepath.Dir(opath)
		var pkg *Package           // if opath belongs to both a package and its test variant, this will be the test variant
		var testVariantOf *Package // if opath is a test file, this is the package it is testing
		var fileExists bool
		isTestFile := strings.HasSuffix(opath, "_test.go")
		pkgName, ok := extractPackageName(opath, contents)
		if !ok {
			// Don't bother adding a file that doesn't even have a parsable package statement
			// to the overlay.
			continue
		}
		// If all the overlay files belong to a different package, change the
		// package name to that package.
		maybeFixPackageName(pkgName, isTestFile, pkgOfDir[dir])
	nextPackage:
		for _, p := range response.dr.Packages {
			if pkgName != p.Name && p.ID != "command-line-arguments" {
				continue
			}
			for _, f := range p.GoFiles {
				if !sameFile(filepath.Dir(f), dir) {
					continue
				}
				// Make sure to capture information on the package's test variant, if needed.
				if isTestFile && !hasTestFiles(p) {
					// TODO(matloob): Are there packages other than the 'production' variant
					// of a package that this can match? This shouldn't match the test main package
					// because the file is generated in another directory.
					testVariantOf = p
					continue nextPackage
				} else if !isTestFile && hasTestFiles(p) {
					// We're examining a test variant, but the overlaid file is
					// a non-test file. Because the overlay implementation
					// (currently) only adds a file to one package, skip this
					// package, so that we can add the file to the production
					// variant of the package. (https://golang.org/issue/36857
					// tracks handling overlays on both the production and test
					// variant of a package).
					continue nextPackage
				}
				if pkg != nil && p != pkg && pkg.PkgPath == p.PkgPath {
					// We have already seen the production version of the
					// for which p is a test variant.
					if hasTestFiles(p) {
						testVariantOf = pkg
					}
				}
				pkg = p
				if filepath.Base(f) == base {
					fileExists = true
				}
			}
		}
		// The overlay could have included an entirely new package or an
		// ad-hoc package. An ad-hoc package is one that we have manually
		// constructed from inadequate `go list` results for a file= query.
		// It will have the ID command-line-arguments.
		if pkg == nil || pkg.ID == "command-line-arguments" {
			// Try to find the module or gopath dir the file is contained in.
			// Then for modules, add the module opath to the beginning.
			pkgPath, ok, err := state.getPkgPath(dir)
			if err != nil {
				return nil, nil, err
			}
			if !ok {
				break
			}
			var forTest string // only set for x tests
			isXTest := strings.HasSuffix(pkgName, "_test")
			if isXTest {
				forTest = pkgPath
				pkgPath += "_test"
			}
			id := pkgPath
			if isTestFile {
				if isXTest {
					id = fmt.Sprintf("%s [%s.test]", pkgPath, forTest)
				} else {
					id = fmt.Sprintf("%s [%s.test]", pkgPath, pkgPath)
				}
			}
			if pkg != nil {
				// TODO(rstambler): We should change the package's path and ID
				// here. The only issue is that this messes with the roots.
			} else {
				// Try to reclaim a package with the same ID, if it exists in the response.
				for _, p := range response.dr.Packages {
					if reclaimPackage(p, id, opath, contents) {
						pkg = p
						break
					}
				}
				// Otherwise, create a new package.
				if pkg == nil {
					pkg = &Package{
						PkgPath: pkgPath,
						ID:      id,
						Name:    pkgName,
						Imports: make(map[string]*Package),
					}
					response.addPackage(pkg)
					havePkgs[pkg.PkgPath] = id
					// Add the production package's sources for a test variant.
					if isTestFile && !isXTest && testVariantOf != nil {
						pkg.GoFiles = append(pkg.GoFiles, testVariantOf.GoFiles...)
						pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, testVariantOf.CompiledGoFiles...)
						// Add the package under test and its imports to the test variant.
						pkg.forTest = testVariantOf.PkgPath
						for k, v := range testVariantOf.Imports {
							pkg.Imports[k] = &Package{ID: v.ID}
						}
					}
					if isXTest {
						pkg.forTest = forTest
					}
				}
			}
		}
		if !fileExists {
			pkg.GoFiles = append(pkg.GoFiles, opath)
			// TODO(matloob): Adding the file to CompiledGoFiles can exhibit the wrong behavior
			// if the file will be ignored due to its build tags.
			pkg.CompiledGoFiles = append(pkg.CompiledGoFiles, opath)
			modifiedPkgsSet[pkg.ID] = true
		}
		imports, err := extractImports(opath, contents)
		if err != nil {
			// Let the parser or type checker report errors later.
			continue
		}
		for _, imp := range imports {
			// TODO(rstambler): If the package is an x test and the import has
			// a test variant, make sure to replace it.
			if _, found := pkg.Imports[imp]; found {
				continue
			}
			overlayAddsImports = true
			id, ok := havePkgs[imp]
			if !ok {
				var err error
				id, err = state.resolveImport(dir, imp)
				if err != nil {
					return nil, nil, err
				}
			}
			pkg.Imports[imp] = &Package{ID: id}
			// Add dependencies to the non-test variant version of this package as well.
			if testVariantOf != nil {
				testVariantOf.Imports[imp] = &Package{ID: id}
			}
		}
	}

	// toPkgPath guesses the package path given the id.
	toPkgPath := func(sourceDir, id string) (string, error) {
		if i := strings.IndexByte(id, ' '); i >= 0 {
			return state.resolveImport(sourceDir, id[:i])
		}
		return state.resolveImport(sourceDir, id)
	}

	// Now that new packages have been created, do another pass to determine
	// the new set of missing packages.
	for _, pkg := range response.dr.Packages {
		for _, imp := range pkg.Imports {
			if len(pkg.GoFiles) == 0 {
				return nil, nil, fmt.Errorf("cannot resolve imports for package %q with no Go files", pkg.PkgPath)
			}
			pkgPath, err := toPkgPath(filepath.Dir(pkg.GoFiles[0]), imp.ID)
			if err != nil {
				return nil, nil, err
			}
			if _, ok := havePkgs[pkgPath]; !ok {
				needPkgsSet[pkgPath] = true
			}
		}
	}

	if overlayAddsImports {
		needPkgs = make([]string, 0, len(needPkgsSet))
		for pkg := range needPkgsSet {
			needPkgs = append(needPkgs, pkg)
		}
	}
	modifiedPkgs = make([]string, 0, len(modifiedPkgsSet))
	for pkg := range modifiedPkgsSet {
		modifiedPkgs = append(modifiedPkgs, pkg)
	}
	return modifiedPkgs, needPkgs, err
}

// resolveImport finds the ID of a package given its import path.
// In particular, it will find the right vendored copy when in GOPATH mode.
func (state *golistState) resolveImport(sourceDir, importPath string) (string, error) {
	env, err := state.getEnv()
	if err != nil {
		return "", err
	}
	if env["GOMOD"] != "" {
		return importPath, nil
	}

	searchDir := sourceDir
	for {
		vendorDir := filepath.Join(searchDir, "vendor")
		exists, ok := state.vendorDirs[vendorDir]
		if !ok {
			info, err := os.Stat(vendorDir)
			exists = err == nil && info.IsDir()
			state.vendorDirs[vendorDir] = exists
		}

		if exists {
			vendoredPath := filepath.Join(vendorDir, importPath)
			if info, err := os.Stat(vendoredPath); err == nil && info.IsDir() {
				// We should probably check for .go files here, but shame on anyone who fools us.
				path, ok, err := state.getPkgPath(vendoredPath)
				if err != nil {
					return "", err
				}
				if ok {
					return path, nil
				}
			}
		}

		// We know we've hit the top of the filesystem when we Dir / and get /,
		// or C:\ and get C:\, etc.
		next := filepath.Dir(searchDir)
		if next == searchDir {
			break
		}
		searchDir = next
	}
	return importPath, nil
}

func hasTestFiles(p *Package) bool {
	for _, f := range p.GoFiles {
		if strings.HasSuffix(f, "_test.go") {
			return true
		}
	}
	return false
}

// determineRootDirs returns a mapping from absolute directories that could
// contain code to their corresponding import path prefixes.
func (state *golistState) determineRootDirs() (map[string]string, error) {
	env, err := state.getEnv()
	if err != nil {
		return nil, err
	}
	if env["GOMOD"] != "" {
		state.rootsOnce.Do(func() {
			state.rootDirs, state.rootDirsError = state.determineRootDirsModules()
		})
	} else {
		state.rootsOnce.Do(func() {
			state.rootDirs, state.rootDirsError = state.determineRootDirsGOPATH()
		})
	}
	return state.rootDirs, state.rootDirsError
}

func (state *golistState) determineRootDirsModules() (map[string]string, error) {
	// List all of the modules--the first will be the directory for the main
	// module. Any replaced modules will also need to be treated as roots.
	// Editing files in the module cache isn't a great idea, so we don't
	// plan to ever support that.
	out, err := state.invokeGo("list", "-m", "-json", "all")
	if err != nil {
		// 'go list all' will fail if we're outside of a module and
		// GO111MODULE=on. Try falling back without 'all'.
		var innerErr error
		out, innerErr = state.invokeGo("list", "-m", "-json")
		if innerErr != nil {
			return nil, err
		}
	}
	roots := map[string]string{}
	modules := map[string]string{}
	var i int
	for dec := json.NewDecoder(out); dec.More(); {
		mod := new(gocommand.ModuleJSON)
		if err := dec.Decode(mod); err != nil {
			return nil, err
		}
		if mod.Dir != "" && mod.Path != "" {
			// This is a valid module; add it to the map.
			absDir, err := filepath.Abs(mod.Dir)
			if err != nil {
				return nil, err
			}
			modules[absDir] = mod.Path
			// The first result is the main module.
			if i == 0 || mod.Replace != nil && mod.Replace.Path != "" {
				roots[absDir] = mod.Path
			}
		}
		i++
	}
	return roots, nil
}

func (state *golistState) determineRootDirsGOPATH() (map[string]string, error) {
	m := map[string]string{}
	for _, dir := range filepath.SplitList(state.mustGetEnv()["GOPATH"]) {
		absDir, err := filepath.Abs(dir)
		if err != nil {
			return nil, err
		}
		m[filepath.Join(absDir, "src")] = ""
	}
	return m, nil
}

func extractImports(filename string, contents []byte) ([]string, error) {
	f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.ImportsOnly) // TODO(matloob): reuse fileset?
	if err != nil {
		return nil, err
	}
	var res []string
	for _, imp := range f.Imports {
		quotedPath := imp.Path.Value
		path, err := strconv.Unquote(quotedPath)
		if err != nil {
			return nil, err
		}
		res = append(res, path)
	}
	return res, nil
}

// reclaimPackage attempts to reuse a package that failed to load in an overlay.
//
// If the package has errors and has no Name, GoFiles, or Imports,
// then it's possible that it doesn't yet exist on disk.
func reclaimPackage(pkg *Package, id string, filename string, contents []byte) bool {
	// TODO(rstambler): Check the message of the actual error?
	// It differs between $GOPATH and module mode.
	if pkg.ID != id {
		return false
	}
	if len(pkg.Errors) != 1 {
		return false
	}
	if pkg.Name != "" || pkg.ExportFile != "" {
		return false
	}
	if len(pkg.GoFiles) > 0 || len(pkg.CompiledGoFiles) > 0 || len(pkg.OtherFiles) > 0 {
		return false
	}
	if len(pkg.Imports) > 0 {
		return false
	}
	pkgName, ok := extractPackageName(filename, contents)
	if !ok {
		return false
	}
	pkg.Name = pkgName
	pkg.Errors = nil
	return true
}

func extractPackageName(filename string, contents []byte) (string, bool) {
	// TODO(rstambler): Check the message of the actual error?
	// It differs between $GOPATH and module mode.
	f, err := parser.ParseFile(token.NewFileSet(), filename, contents, parser.PackageClauseOnly) // TODO(matloob): reuse fileset?
	if err != nil {
		return "", false
	}
	return f.Name.Name, true
}

func commonDir(a []string) string {
	seen := make(map[string]bool)
	x := append([]string{}, a...)
	for _, f := range x {
		seen[filepath.Dir(f)] = true
	}
	if len(seen) > 1 {
		log.Fatalf("commonDir saw %v for %v", seen, x)
	}
	for k := range seen {
		// len(seen) == 1
		return k
	}
	return "" // no files
}

// It is possible that the files in the disk directory dir have a different package
// name from newName, which is deduced from the overlays. If they all have a different
// package name, and they all have the same package name, then that name becomes
// the package name.
// It returns true if it changes the package name, false otherwise.
func maybeFixPackageName(newName string, isTestFile bool, pkgsOfDir []*Package) {
	names := make(map[string]int)
	for _, p := range pkgsOfDir {
		names[p.Name]++
	}
	if len(names) != 1 {
		// some files are in different packages
		return
	}
	var oldName string
	for k := range names {
		oldName = k
	}
	if newName == oldName {
		return
	}
	// We might have a case where all of the package names in the directory are
	// the same, but the overlay file is for an x test, which belongs to its
	// own package. If the x test does not yet exist on disk, we may not yet
	// have its package name on disk, but we should not rename the packages.
	//
	// We use a heuristic to determine if this file belongs to an x test:
	// The test file should have a package name whose package name has a _test
	// suffix or looks like "newName_test".
	maybeXTest := strings.HasPrefix(oldName+"_test", newName) || strings.HasSuffix(newName, "_test")
	if isTestFile && maybeXTest {
		return
	}
	for _, p := range pkgsOfDir {
		p.Name = newName
	}
}

// This function is copy-pasted from
// https://github.com/golang/go/blob/9706f510a5e2754595d716bd64be8375997311fb/src/cmd/go/internal/search/search.go#L360.
// It should be deleted when we remove support for overlays from go/packages.
//
// NOTE: This does not handle any ./... or ./ style queries, as this function
// doesn't know the working directory.
//
// matchPattern(pattern)(name) reports whether
// name matches pattern. Pattern is a limited glob
// pattern in which '...' means 'any string' and there
// is no other special syntax.
// Unfortunately, there are two special cases. Quoting "go help packages":
//
// First, /... at the end of the pattern can match an empty string,
// so that net/... matches both net and packages in its subdirectories, like net/http.
// Second, any slash-separated pattern element containing a wildcard never
// participates in a match of the "vendor" element in the path of a vendored
// package, so that ./... does not match packages in subdirectories of
// ./vendor or ./mycode/vendor, but ./vendor/... and ./mycode/vendor/... do.
// Note, however, that a directory named vendor that itself contains code
// is not a vendored package: cmd/vendor would be a command named vendor,
// and the pattern cmd/... matches it.
func matchPattern(pattern string) func(name string) bool {
	// Convert pattern to regular expression.
	// The strategy for the trailing /... is to nest it in an explicit ? expression.
	// The strategy for the vendor exclusion is to change the unmatchable
	// vendor strings to a disallowed code point (vendorChar) and to use
	// "(anything but that codepoint)*" as the implementation of the ... wildcard.
	// This is a bit complicated but the obvious alternative,
	// namely a hand-written search like in most shell glob matchers,
	// is too easy to make accidentally exponential.
	// Using package regexp guarantees linear-time matching.

	const vendorChar = "\x00"

	if strings.Contains(pattern, vendorChar) {
		return func(name string) bool { return false }
	}

	re := regexp.QuoteMeta(pattern)
	re = replaceVendor(re, vendorChar)
	switch {
	case strings.HasSuffix(re, `/`+vendorChar+`/\.\.\.`):
		re = strings.TrimSuffix(re, `/`+vendorChar+`/\.\.\.`) + `(/vendor|/` + vendorChar + `/\.\.\.)`
	case re == vendorChar+`/\.\.\.`:
		re = `(/vendor|/` + vendorChar + `/\.\.\.)`
	case strings.HasSuffix(re, `/\.\.\.`):
		re = strings.TrimSuffix(re, `/\.\.\.`) + `(/\.\.\.)?`
	}
	re = strings.ReplaceAll(re, `\.\.\.`, `[^`+vendorChar+`]*`)

	reg := regexp.MustCompile(`^` + re + `$`)

	return func(name string) bool {
		if strings.Contains(name, vendorChar) {
			return false
		}
		return reg.MatchString(replaceVendor(name, vendorChar))
	}
}

// replaceVendor returns the result of replacing
// non-trailing vendor path elements in x with repl.
func replaceVendor(x, repl string) string {
	if !strings.Contains(x, "vendor") {
		return x
	}
	elem := strings.Split(x, "/")
	for i := 0; i < len(elem)-1; i++ {
		if elem[i] == "vendor" {
			elem[i] = repl
		}
	}
	return strings.Join(elem, "/")
}
