// Copyright 2011 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 list implements the ``go list'' command.
package list

import (
	"bufio"
	"bytes"
	"context"
	"encoding/json"
	"fmt"
	"io"
	"os"
	"sort"
	"strings"
	"text/template"

	"cmd/go/internal/base"
	"cmd/go/internal/cache"
	"cmd/go/internal/cfg"
	"cmd/go/internal/load"
	"cmd/go/internal/modinfo"
	"cmd/go/internal/modload"
	"cmd/go/internal/str"
	"cmd/go/internal/work"
)

var CmdList = &base.Command{
	// Note: -f -json -m are listed explicitly because they are the most common list flags.
	// Do not send CLs removing them because they're covered by [list flags].
	UsageLine: "go list [-f format] [-json] [-m] [list flags] [build flags] [packages]",
	Short:     "list packages or modules",
	Long: `
List lists the named packages, one per line.
The most commonly-used flags are -f and -json, which control the form
of the output printed for each package. Other list flags, documented below,
control more specific details.

The default output shows the package import path:

    bytes
    encoding/json
    github.com/gorilla/mux
    golang.org/x/net/html

The -f flag specifies an alternate format for the list, using the
syntax of package template. The default output is equivalent
to -f '{{.ImportPath}}'. The struct being passed to the template is:

    type Package struct {
        Dir           string   // directory containing package sources
        ImportPath    string   // import path of package in dir
        ImportComment string   // path in import comment on package statement
        Name          string   // package name
        Doc           string   // package documentation string
        Target        string   // install path
        Shlib         string   // the shared library that contains this package (only set when -linkshared)
        Goroot        bool     // is this package in the Go root?
        Standard      bool     // is this package part of the standard Go library?
        Stale         bool     // would 'go install' do anything for this package?
        StaleReason   string   // explanation for Stale==true
        Root          string   // Go root or Go path dir containing this package
        ConflictDir   string   // this directory shadows Dir in $GOPATH
        BinaryOnly    bool     // binary-only package (no longer supported)
        ForTest       string   // package is only for use in named test
        Export        string   // file containing export data (when using -export)
        BuildID       string   // build ID of the compiled package (when using -export)
        Module        *Module  // info about package's containing module, if any (can be nil)
        Match         []string // command-line patterns matching this package
        DepOnly       bool     // package is only a dependency, not explicitly listed

        // Source files
        GoFiles         []string   // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
        CgoFiles        []string   // .go source files that import "C"
        CompiledGoFiles []string   // .go files presented to compiler (when using -compiled)
        IgnoredGoFiles  []string   // .go source files ignored due to build constraints
        IgnoredOtherFiles []string // non-.go source files ignored due to build constraints
        CFiles          []string   // .c source files
        CXXFiles        []string   // .cc, .cxx and .cpp source files
        MFiles          []string   // .m source files
        HFiles          []string   // .h, .hh, .hpp and .hxx source files
        FFiles          []string   // .f, .F, .for and .f90 Fortran source files
        SFiles          []string   // .s source files
        SwigFiles       []string   // .swig files
        SwigCXXFiles    []string   // .swigcxx files
        SysoFiles       []string   // .syso object files to add to archive
        TestGoFiles     []string   // _test.go files in package
        XTestGoFiles    []string   // _test.go files outside package

        // Embedded files
        EmbedPatterns      []string // //go:embed patterns
        EmbedFiles         []string // files matched by EmbedPatterns
        TestEmbedPatterns  []string // //go:embed patterns in TestGoFiles
        TestEmbedFiles     []string // files matched by TestEmbedPatterns
        XTestEmbedPatterns []string // //go:embed patterns in XTestGoFiles
        XTestEmbedFiles    []string // files matched by XTestEmbedPatterns

        // Cgo directives
        CgoCFLAGS    []string // cgo: flags for C compiler
        CgoCPPFLAGS  []string // cgo: flags for C preprocessor
        CgoCXXFLAGS  []string // cgo: flags for C++ compiler
        CgoFFLAGS    []string // cgo: flags for Fortran compiler
        CgoLDFLAGS   []string // cgo: flags for linker
        CgoPkgConfig []string // cgo: pkg-config names

        // Dependency information
        Imports      []string          // import paths used by this package
        ImportMap    map[string]string // map from source import to ImportPath (identity entries omitted)
        Deps         []string          // all (recursively) imported dependencies
        TestImports  []string          // imports from TestGoFiles
        XTestImports []string          // imports from XTestGoFiles

        // Error information
        Incomplete bool            // this package or a dependency has an error
        Error      *PackageError   // error loading package
        DepsErrors []*PackageError // errors loading dependencies
    }

Packages stored in vendor directories report an ImportPath that includes the
path to the vendor directory (for example, "d/vendor/p" instead of "p"),
so that the ImportPath uniquely identifies a given copy of a package.
The Imports, Deps, TestImports, and XTestImports lists also contain these
expanded import paths. See golang.org/s/go15vendor for more about vendoring.

The error information, if any, is

    type PackageError struct {
        ImportStack   []string // shortest path from package named on command line to this one
        Pos           string   // position of error (if present, file:line:col)
        Err           string   // the error itself
    }

The module information is a Module struct, defined in the discussion
of list -m below.

The template function "join" calls strings.Join.

The template function "context" returns the build context, defined as:

    type Context struct {
        GOARCH        string   // target architecture
        GOOS          string   // target operating system
        GOROOT        string   // Go root
        GOPATH        string   // Go path
        CgoEnabled    bool     // whether cgo can be used
        UseAllFiles   bool     // use files regardless of +build lines, file names
        Compiler      string   // compiler to assume when computing target paths
        BuildTags     []string // build constraints to match in +build lines
        ReleaseTags   []string // releases the current release is compatible with
        InstallSuffix string   // suffix to use in the name of the install dir
    }

For more information about the meaning of these fields see the documentation
for the go/build package's Context type.

The -json flag causes the package data to be printed in JSON format
instead of using the template format.

The -compiled flag causes list to set CompiledGoFiles to the Go source
files presented to the compiler. Typically this means that it repeats
the files listed in GoFiles and then also adds the Go code generated
by processing CgoFiles and SwigFiles. The Imports list contains the
union of all imports from both GoFiles and CompiledGoFiles.

The -deps flag causes list to iterate over not just the named packages
but also all their dependencies. It visits them in a depth-first post-order
traversal, so that a package is listed only after all its dependencies.
Packages not explicitly listed on the command line will have the DepOnly
field set to true.

The -e flag changes the handling of erroneous packages, those that
cannot be found or are malformed. By default, the list command
prints an error to standard error for each erroneous package and
omits the packages from consideration during the usual printing.
With the -e flag, the list command never prints errors to standard
error and instead processes the erroneous packages with the usual
printing. Erroneous packages will have a non-empty ImportPath and
a non-nil Error field; other information may or may not be missing
(zeroed).

The -export flag causes list to set the Export field to the name of a
file containing up-to-date export information for the given package.

The -find flag causes list to identify the named packages but not
resolve their dependencies: the Imports and Deps lists will be empty.

The -test flag causes list to report not only the named packages
but also their test binaries (for packages with tests), to convey to
source code analysis tools exactly how test binaries are constructed.
The reported import path for a test binary is the import path of
the package followed by a ".test" suffix, as in "math/rand.test".
When building a test, it is sometimes necessary to rebuild certain
dependencies specially for that test (most commonly the tested
package itself). The reported import path of a package recompiled
for a particular test binary is followed by a space and the name of
the test binary in brackets, as in "math/rand [math/rand.test]"
or "regexp [sort.test]". The ForTest field is also set to the name
of the package being tested ("math/rand" or "sort" in the previous
examples).

The Dir, Target, Shlib, Root, ConflictDir, and Export file paths
are all absolute paths.

By default, the lists GoFiles, CgoFiles, and so on hold names of files in Dir
(that is, paths relative to Dir, not absolute paths).
The generated files added when using the -compiled and -test flags
are absolute paths referring to cached copies of generated Go source files.
Although they are Go source files, the paths may not end in ".go".

The -m flag causes list to list modules instead of packages.

When listing modules, the -f flag still specifies a format template
applied to a Go struct, but now a Module struct:

    type Module struct {
        Path      string       // module path
        Version   string       // module version
        Versions  []string     // available module versions (with -versions)
        Replace   *Module      // replaced by this module
        Time      *time.Time   // time version was created
        Update    *Module      // available update, if any (with -u)
        Main      bool         // is this the main module?
        Indirect  bool         // is this module only an indirect dependency of main module?
        Dir       string       // directory holding files for this module, if any
        GoMod     string       // path to go.mod file used when loading this module, if any
        GoVersion string       // go version used in module
        Retracted string       // retraction information, if any (with -retracted or -u)
        Error     *ModuleError // error loading module
    }

    type ModuleError struct {
        Err string // the error itself
    }

The file GoMod refers to may be outside the module directory if the
module is in the module cache or if the -modfile flag is used.

The default output is to print the module path and then
information about the version and replacement if any.
For example, 'go list -m all' might print:

    my/main/module
    golang.org/x/text v0.3.0 => /tmp/text
    rsc.io/pdf v0.1.1

The Module struct has a String method that formats this
line of output, so that the default format is equivalent
to -f '{{.String}}'.

Note that when a module has been replaced, its Replace field
describes the replacement module, and its Dir field is set to
the replacement's source code, if present. (That is, if Replace
is non-nil, then Dir is set to Replace.Dir, with no access to
the replaced source code.)

The -u flag adds information about available upgrades.
When the latest version of a given module is newer than
the current one, list -u sets the Module's Update field
to information about the newer module. list -u will also set
the module's Retracted field if the current version is retracted.
The Module's String method indicates an available upgrade by
formatting the newer version in brackets after the current version.
If a version is retracted, the string "(retracted)" will follow it.
For example, 'go list -m -u all' might print:

    my/main/module
    golang.org/x/text v0.3.0 [v0.4.0] => /tmp/text
    rsc.io/pdf v0.1.1 (retracted) [v0.1.2]

(For tools, 'go list -m -u -json all' may be more convenient to parse.)

The -versions flag causes list to set the Module's Versions field
to a list of all known versions of that module, ordered according
to semantic versioning, earliest to latest. The flag also changes
the default output format to display the module path followed by the
space-separated version list.

The -retracted flag causes list to report information about retracted
module versions. When -retracted is used with -f or -json, the Retracted
field will be set to a string explaining why the version was retracted.
The string is taken from comments on the retract directive in the
module's go.mod file. When -retracted is used with -versions, retracted
versions are listed together with unretracted versions. The -retracted
flag may be used with or without -m.

The arguments to list -m are interpreted as a list of modules, not packages.
The main module is the module containing the current directory.
The active modules are the main module and its dependencies.
With no arguments, list -m shows the main module.
With arguments, list -m shows the modules specified by the arguments.
Any of the active modules can be specified by its module path.
The special pattern "all" specifies all the active modules, first the main
module and then dependencies sorted by module path.
A pattern containing "..." specifies the active modules whose
module paths match the pattern.
A query of the form path@version specifies the result of that query,
which is not limited to active modules.
See 'go help modules' for more about module queries.

The template function "module" takes a single string argument
that must be a module path or query and returns the specified
module as a Module struct. If an error occurs, the result will
be a Module struct with a non-nil Error field.

For more about build flags, see 'go help build'.

For more about specifying packages, see 'go help packages'.

For more about modules, see https://golang.org/ref/mod.
	`,
}

func init() {
	CmdList.Run = runList // break init cycle
	work.AddBuildFlags(CmdList, work.DefaultBuildFlags)
}

var (
	listCompiled  = CmdList.Flag.Bool("compiled", false, "")
	listDeps      = CmdList.Flag.Bool("deps", false, "")
	listE         = CmdList.Flag.Bool("e", false, "")
	listExport    = CmdList.Flag.Bool("export", false, "")
	listFmt       = CmdList.Flag.String("f", "", "")
	listFind      = CmdList.Flag.Bool("find", false, "")
	listJson      = CmdList.Flag.Bool("json", false, "")
	listM         = CmdList.Flag.Bool("m", false, "")
	listRetracted = CmdList.Flag.Bool("retracted", false, "")
	listTest      = CmdList.Flag.Bool("test", false, "")
	listU         = CmdList.Flag.Bool("u", false, "")
	listVersions  = CmdList.Flag.Bool("versions", false, "")
)

var nl = []byte{'\n'}

func runList(ctx context.Context, cmd *base.Command, args []string) {
	load.ModResolveTests = *listTest
	work.BuildInit()
	out := newTrackingWriter(os.Stdout)
	defer out.w.Flush()

	if *listFmt == "" {
		if *listM {
			*listFmt = "{{.String}}"
			if *listVersions {
				*listFmt = `{{.Path}}{{range .Versions}} {{.}}{{end}}`
			}
		} else {
			*listFmt = "{{.ImportPath}}"
		}
	}

	var do func(interface{})
	if *listJson {
		do = func(x interface{}) {
			b, err := json.MarshalIndent(x, "", "\t")
			if err != nil {
				out.Flush()
				base.Fatalf("%s", err)
			}
			out.Write(b)
			out.Write(nl)
		}
	} else {
		var cachedCtxt *Context
		context := func() *Context {
			if cachedCtxt == nil {
				cachedCtxt = newContext(&cfg.BuildContext)
			}
			return cachedCtxt
		}
		fm := template.FuncMap{
			"join":    strings.Join,
			"context": context,
			"module":  func(path string) *modinfo.ModulePublic { return modload.ModuleInfo(ctx, path) },
		}
		tmpl, err := template.New("main").Funcs(fm).Parse(*listFmt)
		if err != nil {
			base.Fatalf("%s", err)
		}
		do = func(x interface{}) {
			if err := tmpl.Execute(out, x); err != nil {
				out.Flush()
				base.Fatalf("%s", err)
			}
			if out.NeedNL() {
				out.Write(nl)
			}
		}
	}

	modload.Init()
	if *listRetracted {
		if cfg.BuildMod == "vendor" {
			base.Fatalf("go list -retracted cannot be used when vendoring is enabled")
		}
		if !modload.Enabled() {
			base.Fatalf("go list -retracted can only be used in module-aware mode")
		}
	}

	if *listM {
		// Module mode.
		if *listCompiled {
			base.Fatalf("go list -compiled cannot be used with -m")
		}
		if *listDeps {
			// TODO(rsc): Could make this mean something with -m.
			base.Fatalf("go list -deps cannot be used with -m")
		}
		if *listExport {
			base.Fatalf("go list -export cannot be used with -m")
		}
		if *listFind {
			base.Fatalf("go list -find cannot be used with -m")
		}
		if *listTest {
			base.Fatalf("go list -test cannot be used with -m")
		}

		if modload.Init(); !modload.Enabled() {
			base.Fatalf("go list -m: not using modules")
		}

		modload.LoadModFile(ctx) // Parses go.mod and sets cfg.BuildMod.
		if cfg.BuildMod == "vendor" {
			const actionDisabledFormat = "go list -m: can't %s using the vendor directory\n\t(Use -mod=mod or -mod=readonly to bypass.)"

			if *listVersions {
				base.Fatalf(actionDisabledFormat, "determine available versions")
			}
			if *listU {
				base.Fatalf(actionDisabledFormat, "determine available upgrades")
			}

			for _, arg := range args {
				// In vendor mode, the module graph is incomplete: it contains only the
				// explicit module dependencies and the modules that supply packages in
				// the import graph. Reject queries that imply more information than that.
				if arg == "all" {
					base.Fatalf(actionDisabledFormat, "compute 'all'")
				}
				if strings.Contains(arg, "...") {
					base.Fatalf(actionDisabledFormat, "match module patterns")
				}
			}
		}

		mods := modload.ListModules(ctx, args, *listU, *listVersions, *listRetracted)
		if !*listE {
			for _, m := range mods {
				if m.Error != nil {
					base.Errorf("go list -m: %v", m.Error.Err)
				}
			}
			base.ExitIfErrors()
		}
		for _, m := range mods {
			do(m)
		}
		return
	}

	// Package mode (not -m).
	if *listU {
		base.Fatalf("go list -u can only be used with -m")
	}
	if *listVersions {
		base.Fatalf("go list -versions can only be used with -m")
	}

	// These pairings make no sense.
	if *listFind && *listDeps {
		base.Fatalf("go list -deps cannot be used with -find")
	}
	if *listFind && *listTest {
		base.Fatalf("go list -test cannot be used with -find")
	}

	load.IgnoreImports = *listFind
	pkgs := load.PackagesAndErrors(ctx, args)
	if !*listE {
		w := 0
		for _, pkg := range pkgs {
			if pkg.Error != nil {
				base.Errorf("%v", pkg.Error)
				continue
			}
			pkgs[w] = pkg
			w++
		}
		pkgs = pkgs[:w]
		base.ExitIfErrors()
	}

	if cache.Default() == nil {
		// These flags return file names pointing into the build cache,
		// so the build cache must exist.
		if *listCompiled {
			base.Fatalf("go list -compiled requires build cache")
		}
		if *listExport {
			base.Fatalf("go list -export requires build cache")
		}
		if *listTest {
			base.Fatalf("go list -test requires build cache")
		}
	}

	if *listTest {
		c := cache.Default()
		// Add test binaries to packages to be listed.
		for _, p := range pkgs {
			if len(p.TestGoFiles)+len(p.XTestGoFiles) > 0 {
				var pmain, ptest, pxtest *load.Package
				var err error
				if *listE {
					pmain, ptest, pxtest = load.TestPackagesAndErrors(ctx, p, nil)
				} else {
					pmain, ptest, pxtest, err = load.TestPackagesFor(ctx, p, nil)
					if err != nil {
						base.Errorf("can't load test package: %s", err)
					}
				}
				if pmain != nil {
					pkgs = append(pkgs, pmain)
					data := *pmain.Internal.TestmainGo
					h := cache.NewHash("testmain")
					h.Write([]byte("testmain\n"))
					h.Write(data)
					out, _, err := c.Put(h.Sum(), bytes.NewReader(data))
					if err != nil {
						base.Fatalf("%s", err)
					}
					pmain.GoFiles[0] = c.OutputFile(out)
				}
				if ptest != nil && ptest != p {
					pkgs = append(pkgs, ptest)
				}
				if pxtest != nil {
					pkgs = append(pkgs, pxtest)
				}
			}
		}
	}

	// Remember which packages are named on the command line.
	cmdline := make(map[*load.Package]bool)
	for _, p := range pkgs {
		cmdline[p] = true
	}

	if *listDeps {
		// Note: This changes the order of the listed packages
		// from "as written on the command line" to
		// "a depth-first post-order traversal".
		// (The dependency exploration order for a given node
		// is alphabetical, same as listed in .Deps.)
		// Note that -deps is applied after -test,
		// so that you only get descriptions of tests for the things named
		// explicitly on the command line, not for all dependencies.
		pkgs = loadPackageList(pkgs)
	}

	// Do we need to run a build to gather information?
	needStale := *listJson || strings.Contains(*listFmt, ".Stale")
	if needStale || *listExport || *listCompiled {
		var b work.Builder
		b.Init()
		b.IsCmdList = true
		b.NeedExport = *listExport
		b.NeedCompiledGoFiles = *listCompiled
		a := &work.Action{}
		// TODO: Use pkgsFilter?
		for _, p := range pkgs {
			if len(p.GoFiles)+len(p.CgoFiles) > 0 {
				a.Deps = append(a.Deps, b.AutoAction(work.ModeInstall, work.ModeInstall, p))
			}
		}
		b.Do(ctx, a)
	}

	for _, p := range pkgs {
		// Show vendor-expanded paths in listing
		p.TestImports = p.Resolve(p.TestImports)
		p.XTestImports = p.Resolve(p.XTestImports)
		p.DepOnly = !cmdline[p]

		if *listCompiled {
			p.Imports = str.StringList(p.Imports, p.Internal.CompiledImports)
		}
	}

	if *listTest {
		all := pkgs
		if !*listDeps {
			all = loadPackageList(pkgs)
		}
		// Update import paths to distinguish the real package p
		// from p recompiled for q.test.
		// This must happen only once the build code is done
		// looking at import paths, because it will get very confused
		// if it sees these.
		old := make(map[string]string)
		for _, p := range all {
			if p.ForTest != "" {
				new := p.ImportPath + " [" + p.ForTest + ".test]"
				old[new] = p.ImportPath
				p.ImportPath = new
			}
			p.DepOnly = !cmdline[p]
		}
		// Update import path lists to use new strings.
		m := make(map[string]string)
		for _, p := range all {
			for _, p1 := range p.Internal.Imports {
				if p1.ForTest != "" {
					m[old[p1.ImportPath]] = p1.ImportPath
				}
			}
			for i, old := range p.Imports {
				if new := m[old]; new != "" {
					p.Imports[i] = new
				}
			}
			for old := range m {
				delete(m, old)
			}
		}
		// Recompute deps lists using new strings, from the leaves up.
		for _, p := range all {
			deps := make(map[string]bool)
			for _, p1 := range p.Internal.Imports {
				deps[p1.ImportPath] = true
				for _, d := range p1.Deps {
					deps[d] = true
				}
			}
			p.Deps = make([]string, 0, len(deps))
			for d := range deps {
				p.Deps = append(p.Deps, d)
			}
			sort.Strings(p.Deps)
		}
	}

	// TODO(golang.org/issue/40676): This mechanism could be extended to support
	// -u without -m.
	if *listRetracted {
		// Load retractions for modules that provide packages that will be printed.
		// TODO(golang.org/issue/40775): Packages from the same module refer to
		// distinct ModulePublic instance. It would be nice if they could all point
		// to the same instance. This would require additional global state in
		// modload.loaded, so that should be refactored first. For now, we update
		// all instances.
		modToArg := make(map[*modinfo.ModulePublic]string)
		argToMods := make(map[string][]*modinfo.ModulePublic)
		var args []string
		addModule := func(mod *modinfo.ModulePublic) {
			if mod.Version == "" {
				return
			}
			arg := fmt.Sprintf("%s@%s", mod.Path, mod.Version)
			if argToMods[arg] == nil {
				args = append(args, arg)
			}
			argToMods[arg] = append(argToMods[arg], mod)
			modToArg[mod] = arg
		}
		for _, p := range pkgs {
			if p.Module == nil {
				continue
			}
			addModule(p.Module)
			if p.Module.Replace != nil {
				addModule(p.Module.Replace)
			}
		}

		if len(args) > 0 {
			listU := false
			listVersions := false
			rmods := modload.ListModules(ctx, args, listU, listVersions, *listRetracted)
			for i, arg := range args {
				rmod := rmods[i]
				for _, mod := range argToMods[arg] {
					mod.Retracted = rmod.Retracted
					if rmod.Error != nil && mod.Error == nil {
						mod.Error = rmod.Error
					}
				}
			}
		}
	}

	// Record non-identity import mappings in p.ImportMap.
	for _, p := range pkgs {
		for i, srcPath := range p.Internal.RawImports {
			path := p.Imports[i]
			if path != srcPath {
				if p.ImportMap == nil {
					p.ImportMap = make(map[string]string)
				}
				p.ImportMap[srcPath] = path
			}
		}
	}

	for _, p := range pkgs {
		do(&p.PackagePublic)
	}
}

// loadPackageList is like load.PackageList, but prints error messages and exits
// with nonzero status if listE is not set and any package in the expanded list
// has errors.
func loadPackageList(roots []*load.Package) []*load.Package {
	pkgs := load.PackageList(roots)

	if !*listE {
		for _, pkg := range pkgs {
			if pkg.Error != nil {
				base.Errorf("%v", pkg.Error)
			}
		}
	}

	return pkgs
}

// TrackingWriter tracks the last byte written on every write so
// we can avoid printing a newline if one was already written or
// if there is no output at all.
type TrackingWriter struct {
	w    *bufio.Writer
	last byte
}

func newTrackingWriter(w io.Writer) *TrackingWriter {
	return &TrackingWriter{
		w:    bufio.NewWriter(w),
		last: '\n',
	}
}

func (t *TrackingWriter) Write(p []byte) (n int, err error) {
	n, err = t.w.Write(p)
	if n > 0 {
		t.last = p[n-1]
	}
	return
}

func (t *TrackingWriter) Flush() {
	t.w.Flush()
}

func (t *TrackingWriter) NeedNL() bool {
	return t.last != '\n'
}
