// 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 modcmd implements the ``go mod'' command.
package modcmd

import (
	"bufio"
	"encoding/json"
	"fmt"
	"os"
	"sort"
	"strings"

	"cmd/go/internal/base"
	"cmd/go/internal/modfile"
	"cmd/go/internal/module"
	"cmd/go/internal/par"
	"cmd/go/internal/vgo"
)

var CmdMod = &base.Command{
	UsageLine: "mod [-v] [maintenance flags]",
	Short:     "module maintenance",
	Long: `
Mod performs module maintenance operations as specified by the
following flags, which may be combined.

The -v flag enables additional output about operations performed.

The first group of operations provide low-level editing operations
for manipulating go.mod from the command line or in scripts or
other tools. They read only go.mod itself; they do not look up any
information about the modules involved.

The -init flag initializes and writes a new go.mod to the current directory,
in effect creating a new module rooted at the current directory.
The file go.mod must not already exist.
If possible, mod will guess the module path from import comments
(see 'go help importpath') or from version control configuration.
To override this guess, use the -module flag.
(Without -init, mod applies to the current module.)

The -module flag changes (or, with -init, sets) the module's path
(the go.mod file's module line).

The -require=path@version and -droprequire=path flags
add and drop a requirement on the given module path and version.
Note that -require overrides any existing requirements on path.
These flags are mainly for tools that understand the module graph.
Users should prefer 'go get path@version' or 'go get path@none',
which make other go.mod adjustments as needed to satisfy
constraints imposed by other modules.

The -exclude=path@version and -dropexclude=path@version flags
add and drop an exclusion for the given module path and version.
Note that -exclude=path@version is a no-op if that exclusion already exists.

The -replace=old@v=>new@w and -dropreplace=old@v flags
add and drop a replacement of the given module path and version pair.
Note that -replace overrides any existing replacements for old@v.

These editing flags (-require, -droprequire, -exclude, -dropexclude,
-replace, and -dropreplace) may be repeated.

The -fmt flag reformats the go.mod file without making other changes.
This reformatting is also implied by any other modifications that use or
rewrite the go.mod file. The only time this flag is needed is if no other
flags are specified, as in 'go mod -fmt'.

The -graph flag prints the module requirement graph (with replacements applied)
in text form. Each line in the output has two space-separated fields: a module
and one of its requirements. Each module is identified as a string of the form
path@version, except for the main module, which has no @version suffix.

The -json flag prints the go.mod file in JSON format corresponding to these
Go types:

	type Module struct {
		Path string
		Version string
	}

	type GoMod struct {
		Module Module
		Require []Module
		Exclude []Module
		Replace []struct{ Old, New Module }
	}

Note that this only describes the go.mod file itself, not other modules
referred to indirectly. For the full set of modules available to a build,
use 'go list -m -json all'.

The next group of operations provide higher-level editing and maintenance
of a module, beyond the go.mod file.

The -packages flag prints a list of packages in the module.
It only identifies directories containing Go source code;
it does not check that those directories contain code that builds.

The -fix flag updates go.mod to use canonical version identifiers and
to be semantically consistent. For example, consider this go.mod file:

	module M

	require (
		A v1
		B v1.0.0
		C v1.0.0
		D v1.2.3
		E dev
	)

	exclude D v1.2.3

First, -fix rewrites non-canonical version identifiers to semver form, so
A's v1 becomes v1.0.0 and E's dev becomes the pseudo-version for the latest
commit on the dev branch, perhaps v0.0.0-20180523231146-b3f5c0f6e5f1.

Next, -fix updates requirements to respect exclusions, so the requirement
on the excluded D v1.2.3 is updated to use the next available version of D,
perhaps D v1.2.4 or D v1.3.0.

Finally, -fix removes redundant or misleading requirements.
For example, if A v1.0.0 itself requires B v1.2.0 and C v1.0.0,
then go.mod's requirement of B v1.0.0 is misleading (superseded
by B's need for v1.2.0), and its requirement of C v1.0.0 is redundant
(implied by B's need for the same version), so both will be removed.

Although -fix runs the fix-up operation in isolation, the fix-up also
runs automatically any time a go command uses the module graph,
to update go.mod to reflect reality. For example, the -sync, -vendor,
and -verify flags all effectively imply -fix. And because the module
graph defines the meaning of import statements, any commands
that load packages—'go build', 'go test', 'go list', and so on—also
effectively imply 'go mod -fix'.

The -sync flag synchronizes go.mod with the source code in the module.
It adds any missing modules necessary to build the current module's
packages and dependencies, and it removes unused modules that
don't provide any relevant packages.

The -vendor flag resets the module's vendor directory to include all
packages needed to build and test all the module's packages and
their dependencies.

The -verify flag checks that the dependencies of the current module,
which are stored in a local downloaded source cache, have not been
modified since being downloaded. If all the modules are unmodified,
-verify prints "all modules verified." Otherwise it reports which
modules have been changed and causes 'go mod' to exit with a
non-zero status.
	`,
}

var (
	modV = CmdMod.Flag.Bool("v", false, "")

	modFmt      = CmdMod.Flag.Bool("fmt", false, "")
	modFix      = CmdMod.Flag.Bool("fix", false, "")
	modGraph    = CmdMod.Flag.Bool("graph", false, "")
	modJSON     = CmdMod.Flag.Bool("json", false, "")
	modPackages = CmdMod.Flag.Bool("packages", false, "")
	modSync     = CmdMod.Flag.Bool("sync", false, "")
	modVendor   = CmdMod.Flag.Bool("vendor", false, "")
	modVerify   = CmdMod.Flag.Bool("verify", false, "")

	modEdits []func(*modfile.File) // edits specified in flags
)

type flagFunc func(string)

func (f flagFunc) String() string     { return "" }
func (f flagFunc) Set(s string) error { f(s); return nil }

func init() {
	CmdMod.Run = runMod // break init cycle

	CmdMod.Flag.BoolVar(&vgo.CmdModInit, "init", vgo.CmdModInit, "")
	CmdMod.Flag.StringVar(&vgo.CmdModModule, "module", vgo.CmdModModule, "")

	CmdMod.Flag.Var(flagFunc(flagRequire), "require", "")
	CmdMod.Flag.Var(flagFunc(flagDropRequire), "droprequire", "")
	CmdMod.Flag.Var(flagFunc(flagExclude), "exclude", "")
	CmdMod.Flag.Var(flagFunc(flagDropReplace), "dropreplace", "")
	CmdMod.Flag.Var(flagFunc(flagReplace), "replace", "")
	CmdMod.Flag.Var(flagFunc(flagDropExclude), "dropexclude", "")

	base.AddBuildFlagsNX(&CmdMod.Flag)
}

func runMod(cmd *base.Command, args []string) {
	if vgo.Init(); !vgo.Enabled() {
		base.Fatalf("vgo mod: cannot use outside module")
	}
	if len(args) != 0 {
		base.Fatalf("vgo mod: mod takes no arguments")
	}

	anyFlags :=
		vgo.CmdModInit ||
			vgo.CmdModModule != "" ||
			*modVendor ||
			*modVerify ||
			*modJSON ||
			*modFmt ||
			*modFix ||
			*modGraph ||
			*modPackages ||
			*modSync ||
			len(modEdits) > 0

	if !anyFlags {
		base.Fatalf("vgo mod: no flags specified (see 'go help mod').")
	}

	if vgo.CmdModModule != "" {
		if err := module.CheckPath(vgo.CmdModModule); err != nil {
			base.Fatalf("vgo mod: invalid -module: %v", err)
		}
	}

	if vgo.CmdModInit {
		if _, err := os.Stat("go.mod"); err == nil {
			base.Fatalf("vgo mod -init: go.mod already exists")
		}
	}
	vgo.InitMod()

	// Syntactic edits.

	modFile := vgo.ModFile()
	if vgo.CmdModModule != "" {
		modFile.AddModuleStmt(vgo.CmdModModule)
	}

	if len(modEdits) > 0 {
		for _, edit := range modEdits {
			edit(modFile)
		}
	}
	vgo.WriteGoMod() // write back syntactic changes

	// Semantic edits.

	needBuildList := *modFix || *modGraph

	if *modSync || *modVendor || needBuildList {
		var pkgs []string
		if *modSync || *modVendor {
			pkgs = vgo.ImportPaths([]string{"ALL"})
		} else {
			vgo.LoadBuildList()
		}
		if *modSync {
			// ImportPaths(ALL) already added missing modules.
			// Remove unused modules.
			used := map[module.Version]bool{vgo.Target: true}
			for _, pkg := range pkgs {
				used[vgo.PackageModule(pkg)] = true
			}

			inGoMod := make(map[string]bool)
			for _, r := range vgo.ModFile().Require {
				inGoMod[r.Mod.Path] = true
			}

			var keep []module.Version
			for _, m := range vgo.BuildList() {
				if used[m] {
					keep = append(keep, m)
				} else if *modV && inGoMod[m.Path] {
					fmt.Fprintf(os.Stderr, "unused %s\n", m.Path)
				}
			}
			vgo.SetBuildList(keep)
		}
		vgo.WriteGoMod()
		if *modVendor {
			runVendor()
		}
	}

	// Read-only queries, processed only after updating go.mod.

	if *modJSON {
		modPrintJSON()
	}

	if *modGraph {
		modPrintGraph()
	}

	if *modPackages {
		for _, pkg := range vgo.TargetPackages() {
			fmt.Printf("%s\n", pkg)
		}
	}

	if *modVerify {
		runVerify()
	}
}

// parsePathVersion parses -flag=arg expecting arg to be path@version.
func parsePathVersion(flag, arg string) (path, version string) {
	i := strings.Index(arg, "@")
	if i < 0 {
		base.Fatalf("vgo mod: -%s=%s: need path@version", flag, arg)
	}
	path, version = strings.TrimSpace(arg[:i]), strings.TrimSpace(arg[i+1:])
	if err := module.CheckPath(path); err != nil {
		base.Fatalf("vgo mod: -%s=%s: invalid path: %v", flag, arg, err)
	}

	// We don't call modfile.CheckPathVersion, because that insists
	// on versions being in semver form, but here we want to allow
	// versions like "master" or "1234abcdef", which vgo will resolve
	// the next time it runs (or during -fix).
	// Even so, we need to make sure the version is a valid token.
	if modfile.MustQuote(version) {
		base.Fatalf("vgo mod: -%s=%s: invalid version %q", flag, arg, version)
	}

	return path, version
}

// parsePath parses -flag=arg expecting arg to be path (not path@version).
func parsePath(flag, arg string) (path string) {
	if strings.Contains(arg, "@") {
		base.Fatalf("vgo mod: -%s=%s: need just path, not path@version", flag, arg)
	}
	path = arg
	if err := module.CheckPath(path); err != nil {
		base.Fatalf("vgo mod: -%s=%s: invalid path: %v", flag, arg, err)
	}
	return path
}

// flagRequire implements the -require flag.
func flagRequire(arg string) {
	path, version := parsePathVersion("require", arg)
	modEdits = append(modEdits, func(f *modfile.File) {
		if err := f.AddRequire(path, version); err != nil {
			base.Fatalf("vgo mod: -require=%s: %v", arg, err)
		}
	})
}

// flagDropRequire implements the -droprequire flag.
func flagDropRequire(arg string) {
	path := parsePath("droprequire", arg)
	modEdits = append(modEdits, func(f *modfile.File) {
		if err := f.DropRequire(path); err != nil {
			base.Fatalf("vgo mod: -droprequire=%s: %v", arg, err)
		}
	})
}

// flagExclude implements the -exclude flag.
func flagExclude(arg string) {
	path, version := parsePathVersion("exclude", arg)
	modEdits = append(modEdits, func(f *modfile.File) {
		if err := f.AddExclude(path, version); err != nil {
			base.Fatalf("vgo mod: -exclude=%s: %v", arg, err)
		}
	})
}

// flagDropExclude implements the -dropexclude flag.
func flagDropExclude(arg string) {
	path, version := parsePathVersion("dropexclude", arg)
	modEdits = append(modEdits, func(f *modfile.File) {
		if err := f.DropExclude(path, version); err != nil {
			base.Fatalf("vgo mod: -dropexclude=%s: %v", arg, err)
		}
	})
}

// flagReplace implements the -replace flag.
func flagReplace(arg string) {
	var i int
	if i = strings.Index(arg, "=>"); i < 0 {
		base.Fatalf("vgo mod: -replace=%s: need old@v=>new[@v] (missing =>)", arg)
	}
	old, new := strings.TrimSpace(arg[:i]), strings.TrimSpace(arg[i+2:])
	if i = strings.Index(old, "@"); i < 0 {
		base.Fatalf("vgo mod: -replace=%s: need old@v=>new[@v] (missing @ in old@v)", arg)
	}
	oldPath, oldVersion := strings.TrimSpace(old[:i]), strings.TrimSpace(old[i+1:])
	if err := module.CheckPath(oldPath); err != nil {
		base.Fatalf("vgo mod: -replace=%s: invalid old path: %v", arg, err)
	}
	if modfile.MustQuote(oldVersion) {
		base.Fatalf("vgo mod: -replace=%s: invalid old version %q", arg, oldVersion)
	}
	var newPath, newVersion string
	if i = strings.Index(new, "@"); i >= 0 {
		newPath, newVersion = strings.TrimSpace(new[:i]), strings.TrimSpace(new[i+1:])
		if err := module.CheckPath(newPath); err != nil {
			base.Fatalf("vgo mod: -replace=%s: invalid new path: %v", arg, err)
		}
		if modfile.MustQuote(newVersion) {
			base.Fatalf("vgo mod: -replace=%s: invalid new version %q", arg, newVersion)
		}
	} else {
		if !modfile.IsDirectoryPath(new) {
			base.Fatalf("vgo mod: -replace=%s: unversioned new path must be local directory", arg)
		}
		newPath = new
	}

	modEdits = append(modEdits, func(f *modfile.File) {
		if err := f.AddReplace(oldPath, oldVersion, newPath, newVersion); err != nil {
			base.Fatalf("vgo mod: -replace=%s: %v", arg, err)
		}
	})
}

// flagDropReplace implements the -dropreplace flag.
func flagDropReplace(arg string) {
	path, version := parsePathVersion("dropreplace", arg)
	modEdits = append(modEdits, func(f *modfile.File) {
		if err := f.DropReplace(path, version); err != nil {
			base.Fatalf("vgo mod: -dropreplace=%s: %v", arg, err)
		}
	})
}

// fileJSON is the -json output data structure.
type fileJSON struct {
	Module  module.Version
	Require []module.Version
	Exclude []module.Version
	Replace []replaceJSON
}

type replaceJSON struct {
	Old module.Version
	New module.Version
}

// modPrintJSON prints the -json output.
func modPrintJSON() {
	modFile := vgo.ModFile()

	var f fileJSON
	f.Module = modFile.Module.Mod
	for _, r := range modFile.Require {
		f.Require = append(f.Require, r.Mod)
	}
	for _, x := range modFile.Exclude {
		f.Exclude = append(f.Exclude, x.Mod)
	}
	for _, r := range modFile.Replace {
		f.Replace = append(f.Replace, replaceJSON{r.Old, r.New})
	}
	data, err := json.MarshalIndent(&f, "", "\t")
	if err != nil {
		base.Fatalf("vgo mod -json: internal error: %v", err)
	}
	data = append(data, '\n')
	os.Stdout.Write(data)
}

// modPrintGraph prints the -graph output.
func modPrintGraph() {
	reqs := vgo.Reqs()

	format := func(m module.Version) string {
		if m.Version == "" {
			return m.Path
		}
		return m.Path + "@" + m.Version
	}

	// Note: using par.Work only to manage work queue.
	// No parallelism here, so no locking.
	var out []string
	var deps int // index in out where deps start
	var work par.Work
	work.Add(vgo.Target)
	work.Do(1, func(item interface{}) {
		m := item.(module.Version)
		list, _ := reqs.Required(m)
		for _, r := range list {
			work.Add(r)
			out = append(out, format(m)+" "+format(r)+"\n")
		}
		if m == vgo.Target {
			deps = len(out)
		}
	})

	sort.Slice(out[deps:], func(i, j int) bool {
		return out[deps+i][0] < out[deps+j][0]
	})

	w := bufio.NewWriter(os.Stdout)
	for _, line := range out {
		w.WriteString(line)
	}
	w.Flush()
}
