// 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"
	"encoding/json"
	"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/modload"
	"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: "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: cannot be recompiled from sources
        ForTest       string  // package is only for use in named test
        DepOnly       bool    // package is only a dependency, not explicitly listed
        Export        string  // file containing export data (when using -export)
        Module        *Module // info about package's containing module, if any (can be nil)

        // Source files
        GoFiles        []string // .go source files (excluding CgoFiles, TestGoFiles, XTestGoFiles)
        CgoFiles       []string // .go sources files that import "C"
        IgnoredGoFiles []string // .go sources 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

        // 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 imports 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 -cgo flag causes list to set CgoFiles not to the original *.go files
importing "C" but instead to the translated files generated by the cgo
command.

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 -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 extra entries added by the -cgo 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
        Error    *ModuleError // error loading module
    }

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

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.
The Module's String method indicates an available upgrade by
formatting the newer version in brackets after the current version.
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 [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 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 module' 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 'go help modules'.
	`,
}

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

var (
	listCgo      = CmdList.Flag.Bool("cgo", false, "")
	listDeps     = CmdList.Flag.Bool("deps", false, "")
	listE        = CmdList.Flag.Bool("e", false, "")
	listExport   = CmdList.Flag.Bool("export", false, "")
	listFmt      = CmdList.Flag.String("f", "", "")
	listJson     = CmdList.Flag.Bool("json", false, "")
	listM        = CmdList.Flag.Bool("m", false, "")
	listU        = CmdList.Flag.Bool("u", false, "")
	listTest     = CmdList.Flag.Bool("test", false, "")
	listVersions = CmdList.Flag.Bool("versions", false, "")
)

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

func runList(cmd *base.Command, args []string) {
	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":  modload.ModuleInfo,
		}
		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)
			}
		}
	}

	if *listM {
		// Module mode.
		if *listCgo {
			base.Fatalf("go list -cgo 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 *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.LoadBuildList()

		mods := modload.ListModules(args, *listU, *listVersions)
		if !*listE {
			for _, m := range mods {
				if m.Error != nil {
					base.Errorf("go list -m %s: %v", m.Path, 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")
	}

	var pkgs []*load.Package
	if *listE {
		pkgs = load.PackagesAndErrors(args)
	} else {
		pkgs = load.Packages(args)
	}

	if cache.Default() == nil {
		// These flags return file names pointing into the build cache,
		// so the build cache must exist.
		if *listCgo {
			base.Fatalf("go list -cgo 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 p.Error != nil {
				continue
			}
			if len(p.TestGoFiles)+len(p.XTestGoFiles) > 0 {
				pmain, _, _, err := load.TestPackagesFor(p, nil)
				if err != nil {
					if !*listE {
						base.Errorf("can't load test package: %s", err)
						continue
					}
					pmain = &load.Package{
						PackagePublic: load.PackagePublic{
							ImportPath: p.ImportPath + ".test",
							Error:      &load.PackageError{Err: err.Error()},
						},
					}
				}
				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)
			}
		}
	}

	// 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 = load.PackageList(pkgs)
	}

	// Do we need to run a build to gather information?
	needStale := *listJson || strings.Contains(*listFmt, ".Stale")
	if needStale || *listExport || *listCgo {
		var b work.Builder
		b.Init()
		b.IsCmdList = true
		b.NeedExport = *listExport
		b.NeedCgoFiles = *listCgo
		a := &work.Action{}
		// TODO: Use pkgsFilter?
		for _, p := range pkgs {
			a.Deps = append(a.Deps, b.AutoAction(work.ModeInstall, work.ModeInstall, p))
		}
		b.Do(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 *listTest {
		all := pkgs
		if !*listDeps {
			all = load.PackageList(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)
		}
	}

	// 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)
	}
}

// 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'
}
