// Copyright 2018 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 vgo

import (
	"fmt"
	"go/build"
	"os"
	"path/filepath"
	"sort"
	"strings"

	"cmd/go/internal/base"
	"cmd/go/internal/cfg"
	"cmd/go/internal/imports"
	"cmd/go/internal/module"
	"cmd/go/internal/search"
)

func expandImportPaths(args []string) []string {
	var out []string
	for _, a := range args {
		// TODO(rsc): Move a == "ALL" test into search.IsMetaPackage
		// once we officially lock in all the module work (tentatively, Go 1.12).
		if search.IsMetaPackage(a) || a == "ALL" {
			switch a {
			default:
				fmt.Fprintf(os.Stderr, "vgo: warning: %q matches no packages when using modules\n", a)
			case "all", "ALL":
				out = append(out, AllPackages(a)...)
			}
			continue
		}
		if strings.Contains(a, "...") {
			if build.IsLocalImport(a) {
				out = append(out, search.AllPackagesInFS(a)...)
			} else {
				out = append(out, AllPackages(a)...)
			}
			continue
		}
		out = append(out, a)
	}
	return out
}

// AllPackages returns all the packages that can be found
// under the $GOPATH directories and $GOROOT matching pattern.
// The pattern is either "all" (all packages), "std" (standard packages),
// "cmd" (standard commands), or a path including "...".
func AllPackages(pattern string) []string {
	pkgs := MatchPackages(pattern)
	if len(pkgs) == 0 {
		fmt.Fprintf(os.Stderr, "warning: %q matched no packages\n", pattern)
	}
	return pkgs
}

// MatchPackages returns a list of package paths matching pattern
// (see go help packages for pattern syntax).
func MatchPackages(pattern string) []string {
	if pattern == "std" || pattern == "cmd" {
		return nil
	}
	if pattern == "all" {
		return MatchAll()
	}
	if pattern == "ALL" {
		return MatchALL()
	}

	return matchPackages(pattern, buildList)
}

func matchPackages(pattern string, buildList []module.Version) []string {
	match := func(string) bool { return true }
	treeCanMatch := func(string) bool { return true }
	if !search.IsMetaPackage(pattern) && pattern != "ALL" {
		match = search.MatchPattern(pattern)
		treeCanMatch = search.TreeCanMatchPattern(pattern)
	}

	have := map[string]bool{
		"builtin": true, // ignore pseudo-package that exists only for documentation
	}
	if !cfg.BuildContext.CgoEnabled {
		have["runtime/cgo"] = true // ignore during walk
	}
	var pkgs []string

	for _, mod := range buildList {
		if !treeCanMatch(mod.Path) {
			continue
		}
		var root string
		if mod.Version == "" {
			root = ModRoot
		} else {
			var err error
			root, err = fetch(mod)
			if err != nil {
				base.Errorf("vgo: %v", err)
				continue
			}
		}
		root = filepath.Clean(root)

		filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
			if err != nil {
				return nil
			}

			want := true
			// Avoid .foo, _foo, and testdata directory trees.
			_, elem := filepath.Split(path)
			if strings.HasPrefix(elem, ".") || strings.HasPrefix(elem, "_") || elem == "testdata" {
				want = false
			}

			name := mod.Path + filepath.ToSlash(path[len(root):])
			if !treeCanMatch(name) {
				want = false
			}

			if !fi.IsDir() {
				if fi.Mode()&os.ModeSymlink != 0 && want {
					if target, err := os.Stat(path); err == nil && target.IsDir() {
						fmt.Fprintf(os.Stderr, "warning: ignoring symlink %s\n", path)
					}
				}
				return nil
			}

			if !want {
				return filepath.SkipDir
			}
			if path != root {
				if _, err := os.Stat(filepath.Join(path, "go.mod")); err == nil {
					return filepath.SkipDir
				}
			}

			if !have[name] {
				have[name] = true
				if match(name) {
					if _, _, err := scanDir(path, imports.Tags()); err != imports.ErrNoGo {
						pkgs = append(pkgs, name)
					}
				}
			}

			if elem == "vendor" {
				return filepath.SkipDir
			}
			return nil
		})
	}
	return pkgs
}

// MatchAll returns a list of the packages matching the pattern "all".
// We redefine "all" to mean start with the packages in the current module
// and then follow imports into other modules to add packages imported
// (directly or indirectly) as part of builds in this module.
// It does not include packages in other modules that are not needed
// by builds of this module.
func MatchAll() []string {
	return matchAll(imports.Tags())
}

// MatchALL returns a list of the packages matching the pattern "ALL".
// The pattern "ALL" is like "all" but looks at all source files,
// even ones that would be ignored by current build tag settings.
// That's useful for identifying which packages to include in a vendor directory.
func MatchALL() []string {
	return matchAll(map[string]bool{"*": true})
}

// matchAll is the common implementation of MatchAll and MatchALL,
// which differ only in the set of tags to apply to select files.
func matchAll(tags map[string]bool) []string {
	local := matchPackages("all", buildList[:1])
	ld := newLoader()
	ld.tags = tags
	ld.importList(local, levelTestRecursive)
	var all []string
	for _, pkg := range ld.importmap {
		if !isStandardImportPath(pkg) {
			all = append(all, pkg)
		}
	}
	sort.Strings(all)
	return all
}
