// Copyright 2023 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 toolchain implements dynamic switching of Go toolchains.
package toolchain

import (
	"context"
	"errors"
	"fmt"
	"go/build"
	"io/fs"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strconv"
	"strings"

	"cmd/go/internal/base"
	"cmd/go/internal/cfg"
	"cmd/go/internal/gover"
	"cmd/go/internal/modfetch"
	"cmd/go/internal/modload"
	"cmd/go/internal/run"

	"golang.org/x/mod/module"
)

const (
	// We download golang.org/toolchain version v0.0.1-<gotoolchain>.<goos>-<goarch>.
	// If the 0.0.1 indicates anything at all, its the version of the toolchain packaging:
	// if for some reason we needed to change the way toolchains are packaged into
	// module zip files in a future version of Go, we could switch to v0.0.2 and then
	// older versions expecting the old format could use v0.0.1 and newer versions
	// would use v0.0.2. Of course, then we'd also have to publish two of each
	// module zip file. It's not likely we'll ever need to change this.
	gotoolchainModule  = "golang.org/toolchain"
	gotoolchainVersion = "v0.0.1"

	// targetEnv is a special environment variable set to the expected
	// toolchain version during the toolchain switch by the parent
	// process and cleared in the child process. When set, that indicates
	// to the child to confirm that it provides the expected toolchain version.
	targetEnv = "GOTOOLCHAIN_INTERNAL_SWITCH_VERSION"

	// countEnv is a special environment variable
	// that is incremented during each toolchain switch, to detect loops.
	// It is cleared before invoking programs in 'go run', 'go test', 'go generate', and 'go tool'
	// by invoking them in an environment filtered with FilterEnv,
	// so user programs should not see this in their environment.
	countEnv = "GOTOOLCHAIN_INTERNAL_SWITCH_COUNT"

	// maxSwitch is the maximum toolchain switching depth.
	// Most uses should never see more than three.
	// (Perhaps one for the initial GOTOOLCHAIN dispatch,
	// a second for go get doing an upgrade, and a third if
	// for some reason the chosen upgrade version is too small
	// by a little.)
	// When the count reaches maxSwitch - 10, we start logging
	// the switched versions for debugging before crashing with
	// a fatal error upon reaching maxSwitch.
	// That should be enough to see the repetition.
	maxSwitch = 100
)

// FilterEnv returns a copy of env with internal GOTOOLCHAIN environment
// variables filtered out.
func FilterEnv(env []string) []string {
	// Note: Don't need to filter out targetEnv because Switch does that.
	var out []string
	for _, e := range env {
		if strings.HasPrefix(e, countEnv+"=") {
			continue
		}
		out = append(out, e)
	}
	return out
}

// Select invokes a different Go toolchain if directed by
// the GOTOOLCHAIN environment variable or the user's configuration
// or go.mod file.
// It must be called early in startup.
// See https://go.dev/doc/toolchain#select.
func Select() {
	log.SetPrefix("go: ")
	defer log.SetPrefix("")

	if !modload.WillBeEnabled() {
		return
	}

	// As a special case, let "go env GOTOOLCHAIN" and "go env -w GOTOOLCHAIN=..."
	// be handled by the local toolchain, since an older toolchain may not understand it.
	// This provides an easy way out of "go env -w GOTOOLCHAIN=go1.19" and makes
	// sure that "go env GOTOOLCHAIN" always prints the local go command's interpretation of it.
	// We look for these specific command lines in order to avoid mishandling
	//
	//	GOTOOLCHAIN=go1.999 go env -newflag GOTOOLCHAIN
	//
	// where -newflag is a flag known to Go 1.999 but not known to us.
	if (len(os.Args) == 3 && os.Args[1] == "env" && os.Args[2] == "GOTOOLCHAIN") ||
		(len(os.Args) == 4 && os.Args[1] == "env" && os.Args[2] == "-w" && strings.HasPrefix(os.Args[3], "GOTOOLCHAIN=")) {
		return
	}

	// Interpret GOTOOLCHAIN to select the Go toolchain to run.
	gotoolchain := cfg.Getenv("GOTOOLCHAIN")
	gover.Startup.GOTOOLCHAIN = gotoolchain
	if gotoolchain == "" {
		// cfg.Getenv should fall back to $GOROOT/go.env,
		// so this should not happen, unless a packager
		// has deleted the GOTOOLCHAIN line from go.env.
		// It can also happen if GOROOT is missing or broken,
		// in which case best to let the go command keep running
		// and diagnose the problem.
		return
	}

	// Note: minToolchain is what https://go.dev/doc/toolchain#select calls the default toolchain.
	minToolchain := gover.LocalToolchain()
	minVers := gover.Local()
	var mode string
	if gotoolchain == "auto" {
		mode = "auto"
	} else if gotoolchain == "path" {
		mode = "path"
	} else {
		min, suffix, plus := strings.Cut(gotoolchain, "+") // go1.2.3+auto
		if min != "local" {
			v := gover.FromToolchain(gotoolchain)
			if v == "" {
				if plus {
					base.Fatalf("invalid GOTOOLCHAIN %q: invalid minimum toolchain %q", gotoolchain, min)
				}
				base.Fatalf("invalid GOTOOLCHAIN %q", gotoolchain)
			}
			minToolchain = min
			minVers = v
		}
		if plus && suffix != "auto" && suffix != "path" {
			base.Fatalf("invalid GOTOOLCHAIN %q: only version suffixes are +auto and +path", gotoolchain)
		}
		mode = suffix
	}

	gotoolchain = minToolchain
	if (mode == "auto" || mode == "path") && !goInstallVersion() {
		// Read go.mod to find new minimum and suggested toolchain.
		file, goVers, toolchain := modGoToolchain()
		gover.Startup.AutoFile = file
		if toolchain == "default" {
			// "default" means always use the default toolchain,
			// which is already set, so nothing to do here.
			// Note that if we have Go 1.21 installed originally,
			// GOTOOLCHAIN=go1.30.0+auto or GOTOOLCHAIN=go1.30.0,
			// and the go.mod  says "toolchain default", we use Go 1.30, not Go 1.21.
			// That is, default overrides the "auto" part of the calculation
			// but not the minimum that the user has set.
			// Of course, if the go.mod also says "go 1.35", using Go 1.30
			// will provoke an error about the toolchain being too old.
			// That's what people who use toolchain default want:
			// only ever use the toolchain configured by the user
			// (including its environment and go env -w file).
			gover.Startup.AutoToolchain = toolchain
		} else {
			if toolchain != "" {
				// Accept toolchain only if it is >= our min.
				toolVers := gover.FromToolchain(toolchain)
				if toolVers == "" || (!strings.HasPrefix(toolchain, "go") && !strings.Contains(toolchain, "-go")) {
					base.Fatalf("invalid toolchain %q in %s", toolchain, base.ShortPath(file))
				}
				if gover.Compare(toolVers, minVers) >= 0 {
					gotoolchain = toolchain
					minVers = toolVers
					gover.Startup.AutoToolchain = toolchain
				}
			}
			if gover.Compare(goVers, minVers) > 0 {
				gotoolchain = "go" + goVers
				gover.Startup.AutoGoVersion = goVers
				gover.Startup.AutoToolchain = "" // in case we are overriding it for being too old
			}
		}
	}

	// If we are invoked as a target toolchain, confirm that
	// we provide the expected version and then run.
	// This check is delayed until after the handling of auto and path
	// so that we have initialized gover.Startup for use in error messages.
	if target := os.Getenv(targetEnv); target != "" && TestVersionSwitch != "loop" {
		if gover.LocalToolchain() != target {
			base.Fatalf("toolchain %v invoked to provide %v", gover.LocalToolchain(), target)
		}
		os.Unsetenv(targetEnv)

		// Note: It is tempting to check that if gotoolchain != "local"
		// then target == gotoolchain here, as a sanity check that
		// the child has made the same version determination as the parent.
		// This turns out not always to be the case. Specifically, if we are
		// running Go 1.21 with GOTOOLCHAIN=go1.22+auto, which invokes
		// Go 1.22, then 'go get go@1.23.0' or 'go get needs_go_1_23'
		// will invoke Go 1.23, but as the Go 1.23 child the reason for that
		// will not be apparent here: it will look like we should be using Go 1.22.
		// We rely on the targetEnv being set to know not to downgrade.
		// A longer term problem with the sanity check is that the exact details
		// may change over time: there may be other reasons that a future Go
		// version might invoke an older one, and the older one won't know why.
		// Best to just accept that we were invoked to provide a specific toolchain
		// (which we just checked) and leave it at that.
		return
	}

	if gotoolchain == "local" || gotoolchain == gover.LocalToolchain() {
		// Let the current binary handle the command.
		return
	}

	// Minimal sanity check of GOTOOLCHAIN setting before search.
	// We want to allow things like go1.20.3 but also gccgo-go1.20.3.
	// We want to disallow mistakes / bad ideas like GOTOOLCHAIN=bash,
	// since we will find that in the path lookup.
	if !strings.HasPrefix(gotoolchain, "go1") && !strings.Contains(gotoolchain, "-go1") {
		base.Fatalf("invalid GOTOOLCHAIN %q", gotoolchain)
	}

	Exec(gotoolchain)
}

// TestVersionSwitch is set in the test go binary to the value in $TESTGO_VERSION_SWITCH.
// Valid settings are:
//
//	"switch" - simulate version switches by reinvoking the test go binary with a different TESTGO_VERSION.
//	"mismatch" - like "switch" but forget to set TESTGO_VERSION, so it looks like we invoked a mismatched toolchain
//	"loop" - like "mismatch" but forget the target check, causing a toolchain switching loop
var TestVersionSwitch string

// Exec invokes the specified Go toolchain or else prints an error and exits the process.
// If $GOTOOLCHAIN is set to path or min+path, Exec only considers the PATH
// as a source of Go toolchains. Otherwise Exec tries the PATH but then downloads
// a toolchain if necessary.
func Exec(gotoolchain string) {
	log.SetPrefix("go: ")

	writeBits = sysWriteBits()

	count, _ := strconv.Atoi(os.Getenv(countEnv))
	if count >= maxSwitch-10 {
		fmt.Fprintf(os.Stderr, "go: switching from go%v to %v [depth %d]\n", gover.Local(), gotoolchain, count)
	}
	if count >= maxSwitch {
		base.Fatalf("too many toolchain switches")
	}
	os.Setenv(countEnv, fmt.Sprint(count+1))

	env := cfg.Getenv("GOTOOLCHAIN")
	pathOnly := env == "path" || strings.HasSuffix(env, "+path")

	// For testing, if TESTGO_VERSION is already in use
	// (only happens in the cmd/go test binary)
	// and TESTGO_VERSION_SWITCH=switch is set,
	// "switch" toolchains by changing TESTGO_VERSION
	// and reinvoking the current binary.
	// The special cases =loop and =mismatch skip the
	// setting of TESTGO_VERSION so that it looks like we
	// accidentally invoked the wrong toolchain,
	// to test detection of that failure mode.
	switch TestVersionSwitch {
	case "switch":
		os.Setenv("TESTGO_VERSION", gotoolchain)
		fallthrough
	case "loop", "mismatch":
		exe, err := os.Executable()
		if err != nil {
			base.Fatalf("%v", err)
		}
		execGoToolchain(gotoolchain, os.Getenv("GOROOT"), exe)
	}

	// Look in PATH for the toolchain before we download one.
	// This allows custom toolchains as well as reuse of toolchains
	// already installed using go install golang.org/dl/go1.2.3@latest.
	if exe, err := exec.LookPath(gotoolchain); err == nil {
		execGoToolchain(gotoolchain, "", exe)
	}

	// GOTOOLCHAIN=auto looks in PATH and then falls back to download.
	// GOTOOLCHAIN=path only looks in PATH.
	if pathOnly {
		base.Fatalf("cannot find %q in PATH", gotoolchain)
	}

	// Set up modules without an explicit go.mod, to download distribution.
	modload.Reset()
	modload.ForceUseModules = true
	modload.RootMode = modload.NoRoot
	modload.Init()

	// Download and unpack toolchain module into module cache.
	// Note that multiple go commands might be doing this at the same time,
	// and that's OK: the module cache handles that case correctly.
	m := module.Version{
		Path:    gotoolchainModule,
		Version: gotoolchainVersion + "-" + gotoolchain + "." + runtime.GOOS + "-" + runtime.GOARCH,
	}
	dir, err := modfetch.Download(context.Background(), m)
	if err != nil {
		if errors.Is(err, fs.ErrNotExist) {
			base.Fatalf("download %s for %s/%s: toolchain not available", gotoolchain, runtime.GOOS, runtime.GOARCH)
		}
		base.Fatalf("download %s: %v", gotoolchain, err)
	}

	// On first use after download, set the execute bits on the commands
	// so that we can run them. Note that multiple go commands might be
	// doing this at the same time, but if so no harm done.
	if runtime.GOOS != "windows" {
		info, err := os.Stat(filepath.Join(dir, "bin/go"))
		if err != nil {
			base.Fatalf("download %s: %v", gotoolchain, err)
		}
		if info.Mode()&0111 == 0 {
			// allowExec sets the exec permission bits on all files found in dir.
			allowExec := func(dir string) {
				err := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
					if err != nil {
						return err
					}
					if !d.IsDir() {
						info, err := os.Stat(path)
						if err != nil {
							return err
						}
						if err := os.Chmod(path, info.Mode()&0777|0111); err != nil {
							return err
						}
					}
					return nil
				})
				if err != nil {
					base.Fatalf("download %s: %v", gotoolchain, err)
				}
			}

			// Set the bits in pkg/tool before bin/go.
			// If we are racing with another go command and do bin/go first,
			// then the check of bin/go above might succeed, the other go command
			// would skip its own mode-setting, and then the go command might
			// try to run a tool before we get to setting the bits on pkg/tool.
			// Setting pkg/tool before bin/go avoids that ordering problem.
			// The only other tool the go command invokes is gofmt,
			// so we set that one explicitly before handling bin (which will include bin/go).
			allowExec(filepath.Join(dir, "pkg/tool"))
			allowExec(filepath.Join(dir, "bin/gofmt"))
			allowExec(filepath.Join(dir, "bin"))
		}
	}

	srcUGoMod := filepath.Join(dir, "src/_go.mod")
	srcGoMod := filepath.Join(dir, "src/go.mod")
	if size(srcGoMod) != size(srcUGoMod) {
		err := filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
			if err != nil {
				return err
			}
			if path == srcUGoMod {
				// Leave for last, in case we are racing with another go command.
				return nil
			}
			if pdir, name := filepath.Split(path); name == "_go.mod" {
				if err := raceSafeCopy(path, pdir+"go.mod"); err != nil {
					return err
				}
			}
			return nil
		})
		// Handle src/go.mod; this is the signal to other racing go commands
		// that everything is okay and they can skip this step.
		if err == nil {
			err = raceSafeCopy(srcUGoMod, srcGoMod)
		}
		if err != nil {
			base.Fatalf("download %s: %v", gotoolchain, err)
		}
	}

	// Reinvoke the go command.
	execGoToolchain(gotoolchain, dir, filepath.Join(dir, "bin/go"))
}

func size(path string) int64 {
	info, err := os.Stat(path)
	if err != nil {
		return -1
	}
	return info.Size()
}

var writeBits fs.FileMode

// raceSafeCopy copies the file old to the file new, being careful to ensure
// that if multiple go commands call raceSafeCopy(old, new) at the same time,
// they don't interfere with each other: both will succeed and return and
// later observe the correct content in new. Like in the build cache, we arrange
// this by opening new without truncation and then writing the content.
// Both go commands can do this simultaneously and will write the same thing
// (old never changes content).
func raceSafeCopy(old, new string) error {
	oldInfo, err := os.Stat(old)
	if err != nil {
		return err
	}
	newInfo, err := os.Stat(new)
	if err == nil && newInfo.Size() == oldInfo.Size() {
		return nil
	}
	data, err := os.ReadFile(old)
	if err != nil {
		return err
	}
	// The module cache has unwritable directories by default.
	// Restore the user write bit in the directory so we can create
	// the new go.mod file. We clear it again at the end on a
	// best-effort basis (ignoring failures).
	dir := filepath.Dir(old)
	info, err := os.Stat(dir)
	if err != nil {
		return err
	}
	if err := os.Chmod(dir, info.Mode()|writeBits); err != nil {
		return err
	}
	defer os.Chmod(dir, info.Mode())
	// Note: create the file writable, so that a racing go command
	// doesn't get an error before we store the actual data.
	f, err := os.OpenFile(new, os.O_CREATE|os.O_WRONLY, writeBits&^0o111)
	if err != nil {
		// If OpenFile failed because a racing go command completed our work
		// (and then OpenFile failed because the directory or file is now read-only),
		// count that as a success.
		if size(old) == size(new) {
			return nil
		}
		return err
	}
	defer os.Chmod(new, oldInfo.Mode())
	if _, err := f.Write(data); err != nil {
		f.Close()
		return err
	}
	return f.Close()
}

// modGoToolchain finds the enclosing go.work or go.mod file
// and returns the go version and toolchain lines from the file.
// The toolchain line overrides the version line
func modGoToolchain() (file, goVers, toolchain string) {
	wd := base.UncachedCwd()
	file = modload.FindGoWork(wd)
	// $GOWORK can be set to a file that does not yet exist, if we are running 'go work init'.
	// Do not try to load the file in that case
	if _, err := os.Stat(file); err != nil {
		file = ""
	}
	if file == "" {
		file = modload.FindGoMod(wd)
	}
	if file == "" {
		return "", "", ""
	}

	data, err := os.ReadFile(file)
	if err != nil {
		base.Fatalf("%v", err)
	}
	return file, gover.GoModLookup(data, "go"), gover.GoModLookup(data, "toolchain")
}

// goInstallVersion reports whether the command line is go install m@v or go run m@v.
// If so, Select must not read the go.mod or go.work file in "auto" or "path" mode.
func goInstallVersion() bool {
	// Note: We assume there are no flags between 'go' and 'install' or 'run'.
	// During testing there are some debugging flags that are accepted
	// in that position, but in production go binaries there are not.
	if len(os.Args) < 3 || (os.Args[1] != "install" && os.Args[1] != "run") {
		return false
	}

	// Check for pkg@version.
	var arg string
	switch os.Args[1] {
	default:
		return false
	case "install":
		// We would like to let 'go install -newflag pkg@version' work even
		// across a toolchain switch. To make that work, assume the pkg@version
		// is the last argument and skip the flag parsing.
		arg = os.Args[len(os.Args)-1]
	case "run":
		// For run, the pkg@version can be anywhere on the command line,
		// because it is preceded by run flags and followed by arguments to the
		// program being run. To handle that precisely, we have to interpret the
		// flags a little bit, to know whether each flag takes an optional argument.
		// We can still allow unknown flags as long as they have an explicit =value.
		args := os.Args[2:]
		for i := 0; i < len(args); i++ {
			a := args[i]
			if !strings.HasPrefix(a, "-") {
				arg = a
				break
			}
			if a == "-" {
				// non-flag but also non-pkg@version
				return false
			}
			if a == "--" {
				if i+1 >= len(args) {
					return false
				}
				arg = args[i+1]
				break
			}
			a = strings.TrimPrefix(a, "-")
			a = strings.TrimPrefix(a, "-")
			if strings.HasPrefix(a, "-") {
				// non-flag but also non-pkg@version
				return false
			}
			if strings.Contains(a, "=") {
				// already has value
				continue
			}
			f := run.CmdRun.Flag.Lookup(a)
			if f == nil {
				// Unknown flag. Give up. The command is going to fail in flag parsing.
				return false
			}
			if bf, ok := f.Value.(interface{ IsBoolFlag() bool }); ok && bf.IsBoolFlag() {
				// Does not take value.
				continue
			}
			i++ // Does take a value; skip it.
		}
	}
	if !strings.Contains(arg, "@") || build.IsLocalImport(arg) || filepath.IsAbs(arg) {
		return false
	}
	path, version, _ := strings.Cut(arg, "@")
	if path == "" || version == "" || gover.IsToolchain(path) {
		return false
	}

	// It would be correct to simply return true here, bypassing use
	// of the current go.mod or go.work, and let "go run" or "go install"
	// do the rest, including a toolchain switch.
	// Our goal instead is, since we have gone to the trouble of handling
	// unknown flags to some degree, to run the switch now, so that
	// these commands can switch to a newer toolchain directed by the
	// go.mod which may actually understand the flag.
	// This was brought up during the go.dev/issue/57001 proposal discussion
	// and may end up being common in self-contained "go install" or "go run"
	// command lines if we add new flags in the future.

	// Set up modules without an explicit go.mod, to download go.mod.
	modload.ForceUseModules = true
	modload.RootMode = modload.NoRoot
	modload.Init()
	defer modload.Reset()

	// See internal/load.PackagesAndErrorsOutsideModule
	ctx := context.Background()
	allowed := modload.CheckAllowed
	if modload.IsRevisionQuery(path, version) {
		// Don't check for retractions if a specific revision is requested.
		allowed = nil
	}
	noneSelected := func(path string) (version string) { return "none" }
	_, err := modload.QueryPackages(ctx, path, version, noneSelected, allowed)
	if errors.Is(err, gover.ErrTooNew) {
		// Run early switch, same one go install or go run would eventually do,
		// if it understood all the command-line flags.
		SwitchOrFatal(ctx, err)
	}

	return true // pkg@version found
}
