// Copyright 2017 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 cfg holds configuration shared by multiple parts
// of the go command.
package cfg

import (
	"bytes"
	"context"
	"fmt"
	"go/build"
	"internal/buildcfg"
	"internal/cfg"
	"io"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"sync"

	"cmd/go/internal/fsys"
)

// Global build parameters (used during package load)
var (
	Goos   = envOr("GOOS", build.Default.GOOS)
	Goarch = envOr("GOARCH", build.Default.GOARCH)

	ExeSuffix = exeSuffix()

	// ModulesEnabled specifies whether the go command is running
	// in module-aware mode (as opposed to GOPATH mode).
	// It is equal to modload.Enabled, but not all packages can import modload.
	ModulesEnabled bool
)

func exeSuffix() string {
	if Goos == "windows" {
		return ".exe"
	}
	return ""
}

// Configuration for tools installed to GOROOT/bin.
// Normally these match runtime.GOOS and runtime.GOARCH,
// but when testing a cross-compiled cmd/go they will
// indicate the GOOS and GOARCH of the installed cmd/go
// rather than the test binary.
var (
	installedGOOS   string
	installedGOARCH string
)

// ToolExeSuffix returns the suffix for executables installed
// in build.ToolDir.
func ToolExeSuffix() string {
	if installedGOOS == "windows" {
		return ".exe"
	}
	return ""
}

// These are general "build flags" used by build and other commands.
var (
	BuildA                 bool     // -a flag
	BuildBuildmode         string   // -buildmode flag
	BuildBuildvcs          = "auto" // -buildvcs flag: "true", "false", or "auto"
	BuildContext           = defaultContext()
	BuildMod               string                  // -mod flag
	BuildModExplicit       bool                    // whether -mod was set explicitly
	BuildModReason         string                  // reason -mod was set, if set by default
	BuildLinkshared        bool                    // -linkshared flag
	BuildMSan              bool                    // -msan flag
	BuildASan              bool                    // -asan flag
	BuildCover             bool                    // -cover flag
	BuildCoverMode         string                  // -covermode flag
	BuildCoverPkg          []string                // -coverpkg flag
	BuildN                 bool                    // -n flag
	BuildO                 string                  // -o flag
	BuildP                 = runtime.GOMAXPROCS(0) // -p flag
	BuildPGO               string                  // -pgo flag
	BuildPkgdir            string                  // -pkgdir flag
	BuildRace              bool                    // -race flag
	BuildToolexec          []string                // -toolexec flag
	BuildToolchainName     string
	BuildToolchainCompiler func() string
	BuildToolchainLinker   func() string
	BuildTrimpath          bool // -trimpath flag
	BuildV                 bool // -v flag
	BuildWork              bool // -work flag
	BuildX                 bool // -x flag

	ModCacheRW bool   // -modcacherw flag
	ModFile    string // -modfile flag

	CmdName string // "build", "install", "list", "mod tidy", etc.

	DebugActiongraph  string // -debug-actiongraph flag (undocumented, unstable)
	DebugTrace        string // -debug-trace flag
	DebugRuntimeTrace string // -debug-runtime-trace flag (undocumented, unstable)

	// GoPathError is set when GOPATH is not set. it contains an
	// explanation why GOPATH is unset.
	GoPathError string
)

func defaultContext() build.Context {
	ctxt := build.Default

	ctxt.JoinPath = filepath.Join // back door to say "do not use go command"

	// Override defaults computed in go/build with defaults
	// from go environment configuration file, if known.
	ctxt.GOPATH = envOr("GOPATH", gopath(ctxt))
	ctxt.GOOS = Goos
	ctxt.GOARCH = Goarch

	// Clear the GOEXPERIMENT-based tool tags, which we will recompute later.
	var save []string
	for _, tag := range ctxt.ToolTags {
		if !strings.HasPrefix(tag, "goexperiment.") {
			save = append(save, tag)
		}
	}
	ctxt.ToolTags = save

	// The go/build rule for whether cgo is enabled is:
	//	1. If $CGO_ENABLED is set, respect it.
	//	2. Otherwise, if this is a cross-compile, disable cgo.
	//	3. Otherwise, use built-in default for GOOS/GOARCH.
	// Recreate that logic here with the new GOOS/GOARCH setting.
	if v := Getenv("CGO_ENABLED"); v == "0" || v == "1" {
		ctxt.CgoEnabled = v[0] == '1'
	} else if ctxt.GOOS != runtime.GOOS || ctxt.GOARCH != runtime.GOARCH {
		ctxt.CgoEnabled = false
	} else {
		// Use built-in default cgo setting for GOOS/GOARCH.
		// Note that ctxt.GOOS/GOARCH are derived from the preference list
		// (1) environment, (2) go/env file, (3) runtime constants,
		// while go/build.Default.GOOS/GOARCH are derived from the preference list
		// (1) environment, (2) runtime constants.
		//
		// We know ctxt.GOOS/GOARCH == runtime.GOOS/GOARCH;
		// no matter how that happened, go/build.Default will make the
		// same decision (either the environment variables are set explicitly
		// to match the runtime constants, or else they are unset, in which
		// case go/build falls back to the runtime constants), so
		// go/build.Default.GOOS/GOARCH == runtime.GOOS/GOARCH.
		// So ctxt.CgoEnabled (== go/build.Default.CgoEnabled) is correct
		// as is and can be left unmodified.
		//
		// All that said, starting in Go 1.20 we layer one more rule
		// on top of the go/build decision: if CC is unset and
		// the default C compiler we'd look for is not in the PATH,
		// we automatically default cgo to off.
		// This makes go builds work automatically on systems
		// without a C compiler installed.
		if ctxt.CgoEnabled {
			if os.Getenv("CC") == "" {
				cc := DefaultCC(ctxt.GOOS, ctxt.GOARCH)
				if _, err := LookPath(cc); err != nil {
					ctxt.CgoEnabled = false
				}
			}
		}
	}

	ctxt.OpenFile = func(path string) (io.ReadCloser, error) {
		return fsys.Open(path)
	}
	ctxt.ReadDir = fsys.ReadDir
	ctxt.IsDir = func(path string) bool {
		isDir, err := fsys.IsDir(path)
		return err == nil && isDir
	}

	return ctxt
}

func init() {
	SetGOROOT(Getenv("GOROOT"), false)
	BuildToolchainCompiler = func() string { return "missing-compiler" }
	BuildToolchainLinker = func() string { return "missing-linker" }
}

// SetGOROOT sets GOROOT and associated variables to the given values.
//
// If isTestGo is true, build.ToolDir is set based on the TESTGO_GOHOSTOS and
// TESTGO_GOHOSTARCH environment variables instead of runtime.GOOS and
// runtime.GOARCH.
func SetGOROOT(goroot string, isTestGo bool) {
	BuildContext.GOROOT = goroot

	GOROOT = goroot
	if goroot == "" {
		GOROOTbin = ""
		GOROOTpkg = ""
		GOROOTsrc = ""
	} else {
		GOROOTbin = filepath.Join(goroot, "bin")
		GOROOTpkg = filepath.Join(goroot, "pkg")
		GOROOTsrc = filepath.Join(goroot, "src")
	}
	GOROOT_FINAL = findGOROOT_FINAL(goroot)

	installedGOOS = runtime.GOOS
	installedGOARCH = runtime.GOARCH
	if isTestGo {
		if testOS := os.Getenv("TESTGO_GOHOSTOS"); testOS != "" {
			installedGOOS = testOS
		}
		if testArch := os.Getenv("TESTGO_GOHOSTARCH"); testArch != "" {
			installedGOARCH = testArch
		}
	}

	if runtime.Compiler != "gccgo" {
		if goroot == "" {
			build.ToolDir = ""
		} else {
			// Note that we must use the installed OS and arch here: the tool
			// directory does not move based on environment variables, and even if we
			// are testing a cross-compiled cmd/go all of the installed packages and
			// tools would have been built using the native compiler and linker (and
			// would spuriously appear stale if we used a cross-compiled compiler and
			// linker).
			//
			// This matches the initialization of ToolDir in go/build, except for
			// using ctxt.GOROOT and the installed GOOS and GOARCH rather than the
			// GOROOT, GOOS, and GOARCH reported by the runtime package.
			build.ToolDir = filepath.Join(GOROOTpkg, "tool", installedGOOS+"_"+installedGOARCH)
		}
	}
}

// Experiment configuration.
var (
	// RawGOEXPERIMENT is the GOEXPERIMENT value set by the user.
	RawGOEXPERIMENT = envOr("GOEXPERIMENT", buildcfg.DefaultGOEXPERIMENT)
	// CleanGOEXPERIMENT is the minimal GOEXPERIMENT value needed to reproduce the
	// experiments enabled by RawGOEXPERIMENT.
	CleanGOEXPERIMENT = RawGOEXPERIMENT

	Experiment    *buildcfg.ExperimentFlags
	ExperimentErr error
)

func init() {
	Experiment, ExperimentErr = buildcfg.ParseGOEXPERIMENT(Goos, Goarch, RawGOEXPERIMENT)
	if ExperimentErr != nil {
		return
	}

	// GOEXPERIMENT is valid, so convert it to canonical form.
	CleanGOEXPERIMENT = Experiment.String()

	// Add build tags based on the experiments in effect.
	exps := Experiment.Enabled()
	expTags := make([]string, 0, len(exps)+len(BuildContext.ToolTags))
	for _, exp := range exps {
		expTags = append(expTags, "goexperiment."+exp)
	}
	BuildContext.ToolTags = append(expTags, BuildContext.ToolTags...)
}

// An EnvVar is an environment variable Name=Value.
type EnvVar struct {
	Name  string
	Value string
}

// OrigEnv is the original environment of the program at startup.
var OrigEnv []string

// CmdEnv is the new environment for running go tool commands.
// User binaries (during go test or go run) are run with OrigEnv,
// not CmdEnv.
var CmdEnv []EnvVar

var envCache struct {
	once sync.Once
	m    map[string]string
}

// EnvFile returns the name of the Go environment configuration file.
func EnvFile() (string, error) {
	if file := os.Getenv("GOENV"); file != "" {
		if file == "off" {
			return "", fmt.Errorf("GOENV=off")
		}
		return file, nil
	}
	dir, err := os.UserConfigDir()
	if err != nil {
		return "", err
	}
	if dir == "" {
		return "", fmt.Errorf("missing user-config dir")
	}
	return filepath.Join(dir, "go/env"), nil
}

func initEnvCache() {
	envCache.m = make(map[string]string)
	if file, _ := EnvFile(); file != "" {
		readEnvFile(file, "user")
	}
	goroot := findGOROOT(envCache.m["GOROOT"])
	if goroot != "" {
		readEnvFile(filepath.Join(goroot, "go.env"), "GOROOT")
	}

	// Save the goroot for func init calling SetGOROOT,
	// and also overwrite anything that might have been in go.env.
	// It makes no sense for GOROOT/go.env to specify
	// a different GOROOT.
	envCache.m["GOROOT"] = goroot
}

func readEnvFile(file string, source string) {
	if file == "" {
		return
	}
	data, err := os.ReadFile(file)
	if err != nil {
		return
	}

	for len(data) > 0 {
		// Get next line.
		line := data
		i := bytes.IndexByte(data, '\n')
		if i >= 0 {
			line, data = line[:i], data[i+1:]
		} else {
			data = nil
		}

		i = bytes.IndexByte(line, '=')
		if i < 0 || line[0] < 'A' || 'Z' < line[0] {
			// Line is missing = (or empty) or a comment or not a valid env name. Ignore.
			// This should not happen in the user file, since the file should be maintained almost
			// exclusively by "go env -w", but better to silently ignore than to make
			// the go command unusable just because somehow the env file has
			// gotten corrupted.
			// In the GOROOT/go.env file, we expect comments.
			continue
		}
		key, val := line[:i], line[i+1:]

		if source == "GOROOT" {
			// In the GOROOT/go.env file, do not overwrite fields loaded from the user's go/env file.
			if _, ok := envCache.m[string(key)]; ok {
				continue
			}
		}
		envCache.m[string(key)] = string(val)
	}
}

// Getenv gets the value for the configuration key.
// It consults the operating system environment
// and then the go/env file.
// If Getenv is called for a key that cannot be set
// in the go/env file (for example GODEBUG), it panics.
// This ensures that CanGetenv is accurate, so that
// 'go env -w' stays in sync with what Getenv can retrieve.
func Getenv(key string) string {
	if !CanGetenv(key) {
		switch key {
		case "CGO_TEST_ALLOW", "CGO_TEST_DISALLOW", "CGO_test_ALLOW", "CGO_test_DISALLOW":
			// used by internal/work/security_test.go; allow
		default:
			panic("internal error: invalid Getenv " + key)
		}
	}
	val := os.Getenv(key)
	if val != "" {
		return val
	}
	envCache.once.Do(initEnvCache)
	return envCache.m[key]
}

// CanGetenv reports whether key is a valid go/env configuration key.
func CanGetenv(key string) bool {
	envCache.once.Do(initEnvCache)
	if _, ok := envCache.m[key]; ok {
		// Assume anything in the user file or go.env file is valid.
		return true
	}
	return strings.Contains(cfg.KnownEnv, "\t"+key+"\n")
}

var (
	GOROOT string

	// Either empty or produced by filepath.Join(GOROOT, …).
	GOROOTbin string
	GOROOTpkg string
	GOROOTsrc string

	GOROOT_FINAL string

	GOBIN      = Getenv("GOBIN")
	GOMODCACHE = envOr("GOMODCACHE", gopathDir("pkg/mod"))

	// Used in envcmd.MkEnv and build ID computations.
	GOARM    = envOr("GOARM", fmt.Sprint(buildcfg.GOARM))
	GO386    = envOr("GO386", buildcfg.GO386)
	GOAMD64  = envOr("GOAMD64", fmt.Sprintf("%s%d", "v", buildcfg.GOAMD64))
	GOMIPS   = envOr("GOMIPS", buildcfg.GOMIPS)
	GOMIPS64 = envOr("GOMIPS64", buildcfg.GOMIPS64)
	GOPPC64  = envOr("GOPPC64", fmt.Sprintf("%s%d", "power", buildcfg.GOPPC64))
	GOWASM   = envOr("GOWASM", fmt.Sprint(buildcfg.GOWASM))

	GOPROXY    = envOr("GOPROXY", "")
	GOSUMDB    = envOr("GOSUMDB", "")
	GOPRIVATE  = Getenv("GOPRIVATE")
	GONOPROXY  = envOr("GONOPROXY", GOPRIVATE)
	GONOSUMDB  = envOr("GONOSUMDB", GOPRIVATE)
	GOINSECURE = Getenv("GOINSECURE")
	GOVCS      = Getenv("GOVCS")
)

var SumdbDir = gopathDir("pkg/sumdb")

// GetArchEnv returns the name and setting of the
// GOARCH-specific architecture environment variable.
// If the current architecture has no GOARCH-specific variable,
// GetArchEnv returns empty key and value.
func GetArchEnv() (key, val string) {
	switch Goarch {
	case "arm":
		return "GOARM", GOARM
	case "386":
		return "GO386", GO386
	case "amd64":
		return "GOAMD64", GOAMD64
	case "mips", "mipsle":
		return "GOMIPS", GOMIPS
	case "mips64", "mips64le":
		return "GOMIPS64", GOMIPS64
	case "ppc64", "ppc64le":
		return "GOPPC64", GOPPC64
	case "wasm":
		return "GOWASM", GOWASM
	}
	return "", ""
}

// envOr returns Getenv(key) if set, or else def.
func envOr(key, def string) string {
	val := Getenv(key)
	if val == "" {
		val = def
	}
	return val
}

// There is a copy of findGOROOT, isSameDir, and isGOROOT in
// x/tools/cmd/godoc/goroot.go.
// Try to keep them in sync for now.

// findGOROOT returns the GOROOT value, using either an explicitly
// provided environment variable, a GOROOT that contains the current
// os.Executable value, or else the GOROOT that the binary was built
// with from runtime.GOROOT().
//
// There is a copy of this code in x/tools/cmd/godoc/goroot.go.
func findGOROOT(env string) string {
	if env == "" {
		// Not using Getenv because findGOROOT is called
		// to find the GOROOT/go.env file. initEnvCache
		// has passed in the setting from the user go/env file.
		env = os.Getenv("GOROOT")
	}
	if env != "" {
		return filepath.Clean(env)
	}
	def := ""
	if r := runtime.GOROOT(); r != "" {
		def = filepath.Clean(r)
	}
	if runtime.Compiler == "gccgo" {
		// gccgo has no real GOROOT, and it certainly doesn't
		// depend on the executable's location.
		return def
	}

	// canonical returns a directory path that represents
	// the same directory as dir,
	// preferring the spelling in def if the two are the same.
	canonical := func(dir string) string {
		if isSameDir(def, dir) {
			return def
		}
		return dir
	}

	exe, err := os.Executable()
	if err == nil {
		exe, err = filepath.Abs(exe)
		if err == nil {
			// cmd/go may be installed in GOROOT/bin or GOROOT/bin/GOOS_GOARCH,
			// depending on whether it was cross-compiled with a different
			// GOHOSTOS (see https://go.dev/issue/62119). Try both.
			if dir := filepath.Join(exe, "../.."); isGOROOT(dir) {
				return canonical(dir)
			}
			if dir := filepath.Join(exe, "../../.."); isGOROOT(dir) {
				return canonical(dir)
			}

			// Depending on what was passed on the command line, it is possible
			// that os.Executable is a symlink (like /usr/local/bin/go) referring
			// to a binary installed in a real GOROOT elsewhere
			// (like /usr/lib/go/bin/go).
			// Try to find that GOROOT by resolving the symlinks.
			exe, err = filepath.EvalSymlinks(exe)
			if err == nil {
				if dir := filepath.Join(exe, "../.."); isGOROOT(dir) {
					return canonical(dir)
				}
				if dir := filepath.Join(exe, "../../.."); isGOROOT(dir) {
					return canonical(dir)
				}
			}
		}
	}
	return def
}

func findGOROOT_FINAL(goroot string) string {
	// $GOROOT_FINAL is only for use during make.bash
	// so it is not settable using go/env, so we use os.Getenv here.
	def := goroot
	if env := os.Getenv("GOROOT_FINAL"); env != "" {
		def = filepath.Clean(env)
	}
	return def
}

// isSameDir reports whether dir1 and dir2 are the same directory.
func isSameDir(dir1, dir2 string) bool {
	if dir1 == dir2 {
		return true
	}
	info1, err1 := os.Stat(dir1)
	info2, err2 := os.Stat(dir2)
	return err1 == nil && err2 == nil && os.SameFile(info1, info2)
}

// isGOROOT reports whether path looks like a GOROOT.
//
// It does this by looking for the path/pkg/tool directory,
// which is necessary for useful operation of the cmd/go tool,
// and is not typically present in a GOPATH.
//
// There is a copy of this code in x/tools/cmd/godoc/goroot.go.
func isGOROOT(path string) bool {
	stat, err := os.Stat(filepath.Join(path, "pkg", "tool"))
	if err != nil {
		return false
	}
	return stat.IsDir()
}

func gopathDir(rel string) string {
	list := filepath.SplitList(BuildContext.GOPATH)
	if len(list) == 0 || list[0] == "" {
		return ""
	}
	return filepath.Join(list[0], rel)
}

func gopath(ctxt build.Context) string {
	if len(ctxt.GOPATH) > 0 {
		return ctxt.GOPATH
	}
	env := "HOME"
	if runtime.GOOS == "windows" {
		env = "USERPROFILE"
	} else if runtime.GOOS == "plan9" {
		env = "home"
	}
	if home := os.Getenv(env); home != "" {
		def := filepath.Join(home, "go")
		if filepath.Clean(def) == filepath.Clean(runtime.GOROOT()) {
			GoPathError = "cannot set GOROOT as GOPATH"
		}
		return ""
	}
	GoPathError = fmt.Sprintf("%s is not set", env)
	return ""
}

// WithBuildXWriter returns a Context in which BuildX output is written
// to given io.Writer.
func WithBuildXWriter(ctx context.Context, xLog io.Writer) context.Context {
	return context.WithValue(ctx, buildXContextKey{}, xLog)
}

type buildXContextKey struct{}

// BuildXWriter returns nil if BuildX is false, or
// the writer to which BuildX output should be written otherwise.
func BuildXWriter(ctx context.Context) (io.Writer, bool) {
	if !BuildX {
		return nil, false
	}
	if v := ctx.Value(buildXContextKey{}); v != nil {
		return v.(io.Writer), true
	}
	return os.Stderr, true
}
