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

import (
	"context"
	"fmt"
	"os"
	"path/filepath"
	"sort"
	"strings"

	"cmd/go/internal/base"
	"cmd/go/internal/cfg"
	"cmd/go/internal/gover"
	"cmd/go/internal/modfetch"
)

// A Switcher collects errors to be reported and then decides
// between reporting the errors or switching to a new toolchain
// to resolve them.
//
// The client calls [Switcher.Error] repeatedly with errors encountered
// and then calls [Switcher.Switch]. If the errors included any
// *gover.TooNewErrors (potentially wrapped) and switching is
// permitted by GOTOOLCHAIN, Switch switches to a new toolchain.
// Otherwise Switch prints all the errors using base.Error.
//
// See https://go.dev/doc/toolchain#switch.
type Switcher struct {
	TooNew *gover.TooNewError // max go requirement observed
	Errors []error            // errors collected so far
}

// Error reports the error to the Switcher,
// which saves it for processing during Switch.
func (s *Switcher) Error(err error) {
	s.Errors = append(s.Errors, err)
	s.addTooNew(err)
}

// addTooNew adds any TooNew errors that can be found in err.
func (s *Switcher) addTooNew(err error) {
	switch err := err.(type) {
	case interface{ Unwrap() []error }:
		for _, e := range err.Unwrap() {
			s.addTooNew(e)
		}

	case interface{ Unwrap() error }:
		s.addTooNew(err.Unwrap())

	case *gover.TooNewError:
		if s.TooNew == nil ||
			gover.Compare(err.GoVersion, s.TooNew.GoVersion) > 0 ||
			gover.Compare(err.GoVersion, s.TooNew.GoVersion) == 0 && err.What < s.TooNew.What {
			s.TooNew = err
		}
	}
}

// NeedSwitch reports whether Switch would attempt to switch toolchains.
func (s *Switcher) NeedSwitch() bool {
	return s.TooNew != nil && (HasAuto() || HasPath())
}

// Switch decides whether to switch to a newer toolchain
// to resolve any of the saved errors.
// It switches if toolchain switches are permitted and there is at least one TooNewError.
//
// If Switch decides not to switch toolchains, it prints the errors using base.Error and returns.
//
// If Switch decides to switch toolchains but cannot identify a toolchain to use.
// it prints the errors along with one more about not being able to find the toolchain
// and returns.
//
// Otherwise, Switch prints an informational message giving a reason for the
// switch and the toolchain being invoked and then switches toolchains.
// This operation never returns.
func (s *Switcher) Switch(ctx context.Context) {
	if !s.NeedSwitch() {
		for _, err := range s.Errors {
			base.Error(err)
		}
		return
	}

	// Switch to newer Go toolchain if necessary and possible.
	tv, err := NewerToolchain(ctx, s.TooNew.GoVersion)
	if err != nil {
		for _, err := range s.Errors {
			base.Error(err)
		}
		base.Error(fmt.Errorf("switching to go >= %v: %w", s.TooNew.GoVersion, err))
		return
	}

	fmt.Fprintf(os.Stderr, "go: %v requires go >= %v; switching to %v\n", s.TooNew.What, s.TooNew.GoVersion, tv)
	Exec(tv)
	panic("unreachable")
}

// SwitchOrFatal attempts a toolchain switch based on the information in err
// and otherwise falls back to base.Fatal(err).
func SwitchOrFatal(ctx context.Context, err error) {
	var s Switcher
	s.Error(err)
	s.Switch(ctx)
	base.Exit()
}

// NewerToolchain returns the name of the toolchain to use when we need
// to switch to a newer toolchain that must support at least the given Go version.
// See https://go.dev/doc/toolchain#switch.
//
// If the latest major release is 1.N.0, we use the latest patch release of 1.(N-1) if that's >= version.
// Otherwise we use the latest 1.N if that's allowed.
// Otherwise we use the latest release.
func NewerToolchain(ctx context.Context, version string) (string, error) {
	fetch := autoToolchains
	if !HasAuto() {
		fetch = pathToolchains
	}
	list, err := fetch(ctx)
	if err != nil {
		return "", err
	}
	return newerToolchain(version, list)
}

// autoToolchains returns the list of toolchain versions available to GOTOOLCHAIN=auto or =min+auto mode.
func autoToolchains(ctx context.Context) ([]string, error) {
	var versions *modfetch.Versions
	err := modfetch.TryProxies(func(proxy string) error {
		v, err := modfetch.Lookup(ctx, proxy, "go").Versions(ctx, "")
		if err != nil {
			return err
		}
		versions = v
		return nil
	})
	if err != nil {
		return nil, err
	}
	return versions.List, nil
}

// pathToolchains returns the list of toolchain versions available to GOTOOLCHAIN=path or =min+path mode.
func pathToolchains(ctx context.Context) ([]string, error) {
	have := make(map[string]bool)
	var list []string
	for _, dir := range pathDirs() {
		if dir == "" || !filepath.IsAbs(dir) {
			// Refuse to use local directories in $PATH (hard-coding exec.ErrDot).
			continue
		}
		entries, err := os.ReadDir(dir)
		if err != nil {
			continue
		}
		for _, de := range entries {
			if de.IsDir() || !strings.HasPrefix(de.Name(), "go1.") {
				continue
			}
			info, err := de.Info()
			if err != nil {
				continue
			}
			v, ok := pathVersion(dir, de, info)
			if !ok || !strings.HasPrefix(v, "1.") || have[v] {
				continue
			}
			have[v] = true
			list = append(list, v)
		}
	}
	sort.Slice(list, func(i, j int) bool {
		return gover.Compare(list[i], list[j]) < 0
	})
	return list, nil
}

// newerToolchain implements NewerToolchain where the list of choices is known.
// It is separated out for easier testing of this logic.
func newerToolchain(need string, list []string) (string, error) {
	// Consider each release in the list, from newest to oldest,
	// considering only entries >= need and then only entries
	// that are the latest in their language family
	// (the latest 1.40, the latest 1.39, and so on).
	// We prefer the latest patch release before the most recent release family,
	// so if the latest release is 1.40.1 we'll take the latest 1.39.X.
	// Failing that, we prefer the latest patch release before the most recent
	// prerelease family, so if the latest release is 1.40rc1 is out but 1.39 is okay,
	// we'll still take 1.39.X.
	// Failing that we'll take the latest release.
	latest := ""
	for i := len(list) - 1; i >= 0; i-- {
		v := list[i]
		if gover.Compare(v, need) < 0 {
			break
		}
		if gover.Lang(latest) == gover.Lang(v) {
			continue
		}
		newer := latest
		latest = v
		if newer != "" && !gover.IsPrerelease(newer) {
			// latest is the last patch release of Go 1.X, and we saw a non-prerelease of Go 1.(X+1),
			// so latest is the one we want.
			break
		}
	}
	if latest == "" {
		return "", fmt.Errorf("no releases found for go >= %v", need)
	}
	return "go" + latest, nil
}

// HasAuto reports whether the GOTOOLCHAIN setting allows "auto" upgrades.
func HasAuto() bool {
	env := cfg.Getenv("GOTOOLCHAIN")
	return env == "auto" || strings.HasSuffix(env, "+auto")
}

// HasPath reports whether the GOTOOLCHAIN setting allows "path" upgrades.
func HasPath() bool {
	env := cfg.Getenv("GOTOOLCHAIN")
	return env == "path" || strings.HasSuffix(env, "+path")
}
