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

//go:generate go run . -w

//go:build go1.21

// Package configgen generates the upload config file stored in the config.json
// file of golang.org/x/telemetry/config based on the chartconfig stored in
// config.txt.
package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"slices"
	"sort"
	"strings"

	"golang.org/x/mod/semver"
	"golang.org/x/telemetry/internal/chartconfig"
	"golang.org/x/telemetry/internal/telemetry"
)

var (
	write = flag.Bool("w", false, "if set, write the config file; otherwise, print to stdout")
	force = flag.Bool("f", false, "if set, force the write of the config file even if the current content is still valid")

	// SamplingRate is the fraction of otherwise uploadable reports that will be uploaded
	SamplingRate = 1.0
)

func main() {
	flag.Parse()

	gcfgs, err := chartconfig.Load()
	if err != nil {
		log.Fatal(err)
	}

	// The padding heuristics below are based on the example of gopls.
	//
	// The goal is to pad enough versions for a quarter.
	uCfg, err := generate(gcfgs, padding{
		// 6 releases into the future translates to approximately three months for gopls.
		releases: 6,
		// We may release gopls 1.0, but won't release 2.0 in a three month timespan!
		maj: 1,
		// We don't usually do more than one minor release a month.
		majmin: 3,
		// Since golang/go#55267, which committed to adhering to semver, gopls
		// hasn't had more than 5 patches per minor version.
		patch: 6,
		// Gopls has never had more than 4 prereleases.
		pre: 4,
	})

	if err != nil {
		log.Fatal(err)
	}
	cfgJSON, err := json.MarshalIndent(uCfg, "", "\t")
	if err != nil {
		log.Fatal(err)
	}

	if !*write {
		fmt.Println(string(cfgJSON))
		os.Exit(0)
	}

	configFile, err := configFile()
	if err != nil {
		log.Fatalf("finding config file: %v", err)
	}

	if !*force {
		currentCfg, err := readConfig(configFile)
		if err != nil {
			log.Fatal(err)
		}
		// Guarantee that we have enough padding to do two patches releases tomorrow.
		minCfg, err := generate(gcfgs, padding{
			releases: 2,
			maj:      1,
			majmin:   1, // we're not ever going to do more than one major/minor release in a day
			patch:    2,
			pre:      2, // in a single day, we wouldn't prep more than two prereleases per version
		})
		if err != nil {
			log.Fatal(err)
		}
		if contains(currentCfg, minCfg) {
			fmt.Fprintln(os.Stderr, "not writing the config file as it is still valid; use -f to force")
			os.Exit(0)
		}
	}
	if err := os.WriteFile(configFile, cfgJSON, 0666); err != nil {
		log.Fatal(err)
	}
}

// configFile returns the path to the x/telemetry/config config.json file in
// this repo.
//
// The file must already exist: this won't be a valid location if running from
// the module cache; this functionality only works when executed from the
// telemetry repo.
func configFile() (string, error) {
	out, err := exec.Command("go", "list", "-f", "{{.Dir}}", "golang.org/x/telemetry/internal/configgen").Output()
	if err != nil {
		return "", err
	}
	dir := strings.TrimSpace(string(out))
	configFile := filepath.Join(dir, "..", "..", "config", "config.json")
	if _, err := os.Stat(configFile); err != nil {
		return "", err
	}
	return configFile, nil
}

func readConfig(file string) (*telemetry.UploadConfig, error) {
	data, err := os.ReadFile(file)
	if err != nil {
		return nil, fmt.Errorf("reading config file: %v", err)
	}
	cfg := new(telemetry.UploadConfig)
	if err := json.Unmarshal(data, cfg); err != nil {
		return nil, fmt.Errorf("unmarshalling config file: %v", err)
	}
	return cfg, nil
}

// generate computes the upload config from chart configs and module
// information, returning the resulting formatted JSON.
func generate(gcfgs []chartconfig.ChartConfig, padding padding) (*telemetry.UploadConfig, error) {
	ucfg := &telemetry.UploadConfig{
		GOOS:   goos(),
		GOARCH: goarch(),
		// the probability of uploading a report
		SampleRate: SamplingRate,
	}
	var err error
	ucfg.GoVersion, err = goVersions()
	if err != nil {
		return nil, fmt.Errorf("querying go info: %v", err)
	}

	for i, r := range gcfgs {
		if err := chartconfig.Validate(r); err != nil {
			// TODO(rfindley): this is a poor way to identify the faulty record. We
			// should probably store position information in the ChartConfig.
			return nil, fmt.Errorf("chart config #%d (%q): %v", i, r.Title, err)
		}
	}

	var (
		programs    = make(map[string]*telemetry.ProgramConfig) // package path -> config
		minVersions = make(map[string]string)                   // package path -> min version required, or "" for all
	)
	for _, gcfg := range gcfgs {
		pcfg := programs[gcfg.Program]
		if pcfg == nil {
			pcfg = &telemetry.ProgramConfig{
				Name: gcfg.Program,
			}
			programs[gcfg.Program] = pcfg
			minVersions[gcfg.Program] = gcfg.Version
		}
		minVersions[gcfg.Program] = minVersion(minVersions[gcfg.Program], gcfg.Version)
		ccfg := telemetry.CounterConfig{
			Name:  gcfg.Counter,
			Rate:  1.0, // TODO(rfindley): how should rate be configured?
			Depth: gcfg.Depth,
		}
		if gcfg.Depth > 0 {
			pcfg.Stacks = append(pcfg.Stacks, ccfg)
		} else {
			pcfg.Counters = append(pcfg.Counters, ccfg)
		}
	}

	for _, p := range programs {
		minVersion := minVersions[p.Name]
		versions, err := listProxyVersions(p.Name)
		if err != nil {
			return nil, fmt.Errorf("listing versions for %q: %v", p.Name, err)
		}
		// Filter proxy versions in place.
		i := 0
		for _, v := range versions {
			if !semver.IsValid(v) {
				// In order to perform semver comparison below, we must have valid
				// versions. This should always be the case for the proxy.
				// Trust, but verify.
				return nil, fmt.Errorf("invalid semver %q returned from proxy for %q", v, p.Name)
			}
			if minVersion == "" || semver.Compare(minVersion, v) <= 0 {
				versions[i] = v
				i++
			}
		}
		p.Versions = padVersions(versions[:i], prereleasesForProgram(p.Name), padding)
		// TODO(hakim): allow to collect counters from gopls@devel. go.dev/issues/62271
		if p.Name == "golang.org/x/tools/gopls" {
			p.Versions = append(p.Versions, "devel") // added at the end.
		}
		ucfg.Programs = append(ucfg.Programs, p)
	}
	sort.Slice(ucfg.Programs, func(i, j int) bool {
		return ucfg.Programs[i].Name < ucfg.Programs[j].Name
	})

	return ucfg, nil
}

// contains reports whether outer contains all program versions of inner, and
// is otherwise equivalent to inner.
func contains(outer, inner *telemetry.UploadConfig) bool {
	if !slices.Equal(outer.GOARCH, inner.GOARCH) {
		return false
	}
	if !slices.Equal(outer.GOOS, inner.GOOS) {
		return false
	}
	if !slices.Equal(outer.GoVersion, inner.GoVersion) {
		return false
	}

	for _, pi := range inner.Programs {
		i := slices.IndexFunc(outer.Programs, func(po *telemetry.ProgramConfig) bool {
			return po.Name == pi.Name
		})
		if i < 0 {
			return false
		}
		po := outer.Programs[i]
		if !sliceContains(po.Versions, pi.Versions) {
			return false
		}
		if !slices.Equal(po.Counters, pi.Counters) {
			return false
		}
		if !slices.Equal(po.Stacks, pi.Stacks) {
			return false
		}
	}
	for _, po := range outer.Programs {
		if !slices.ContainsFunc(inner.Programs, func(pi *telemetry.ProgramConfig) bool {
			return pi.Name == po.Name
		}) {
			return false
		}
	}
	return true
}

func sliceContains[T comparable](outer, inner []T) bool {
	m := toMap(outer)
	for _, v := range inner {
		if !m[v] {
			return false
		}
	}
	return true
}

func toMap[T comparable](s []T) map[T]bool {
	m := make(map[T]bool)
	for _, v := range s {
		m[v] = true
	}
	return m
}

// prereleasesForProgram returns the set of prereleases to use for the provided
// program. We may need to customize this for the conventions of different
// programs.
func prereleasesForProgram(program string) []string {
	// Surely eight prereleases is enough for any program... :)
	return []string{"pre.1", "pre.2", "pre.3", "pre.4", "pre.5", "pre.6", "pre.7", "pre.8"}
}

// minVersion returns the lesser semantic version of v1 and v2.
//
// As a special case, the empty string is treated as an absolute minimum
// (empty => all versions are greater).
func minVersion(v1, v2 string) string {
	if v1 == "" || v2 == "" {
		return ""
	}
	if semver.Compare(v1, v2) > 0 {
		return v2
	}
	return v1
}

// goos returns a sorted slice of known GOOS values.
func goos() []string {
	var gooses []string
	for goos := range knownOS {
		gooses = append(gooses, goos)
	}
	sort.Strings(gooses)
	return gooses
}

// goarch returns a sorted slice of known GOARCH values.
func goarch() []string {
	var arches []string
	for arch := range knownArch {
		arches = append(arches, arch)
	}
	sort.Strings(arches)
	return arches
}

// goInfo queries the proxy for information about go distributions, including
// versions, GOOS, and GOARCH values.
func goVersions() ([]string, error) {
	// Trick: read Go distribution information from the module versions of
	// golang.org/toolchain. These define the set of valid toolchains, and
	// therefore are a reasonable source for version information.
	//
	// A more authoritative source for this information may be
	// https://go.dev/dl?mode=json&include=all.
	proxyVersions, err := listProxyVersions("golang.org/toolchain")
	if err != nil {
		return nil, fmt.Errorf("listing toolchain versions: %v", err)
	}
	var goVersionRx = regexp.MustCompile(`^-(go.+)\.[^.]+-[^.]+$`)
	verSet := make(map[string]struct{})
	for _, v := range proxyVersions {
		pre := semver.Prerelease(v)
		match := goVersionRx.FindStringSubmatch(pre)
		if match == nil {
			return nil, fmt.Errorf("proxy version %q does not match prerelease regexp %q", v, goVersionRx)
		}
		verSet[match[1]] = struct{}{}
	}
	var vers []string
	for v := range verSet {
		vers = append(vers, v)
	}
	sort.Sort(byGoVersion(vers))
	// TODO(golang/go#62271): temporarily monitor 'devel'.
	vers = append(vers, "devel")
	return vers, nil
}

type byGoVersion []string

func (vs byGoVersion) Len() int      { return len(vs) }
func (vs byGoVersion) Swap(i, j int) { vs[i], vs[j] = vs[j], vs[i] }
func (vs byGoVersion) Less(i, j int) bool {
	cmp := Compare(vs[i], vs[j])
	if cmp != 0 {
		return cmp < 0
	}
	// To ensure that we have a stable sort, order equivalent Go versions lexically.
	return vs[i] < vs[j]
}

// versionsForTesting contains versions to use for testing, rather than
// querying the proxy.
var versionsForTesting map[string][]string

// listProxyVersions queries the Go module mirror for published versions of the
// given modulePath.
//
// modulePath must be lower-case (or already escaped): this function doesn't do
// any escaping of upper-cased letters, as is required by the proxy prototol
// (https://go.dev/ref/mod#goproxy-protocol).
func listProxyVersions(modulePath string) ([]string, error) {
	if vers, ok := versionsForTesting[modulePath]; ok {
		return vers, nil
	}
	cmd := exec.Command("go", "list", "-m", "--versions", modulePath)
	var stderr bytes.Buffer
	cmd.Stderr = &stderr
	out, err := cmd.Output()
	if err != nil {
		return nil, fmt.Errorf("listing versions: %v (stderr: %v)", err, stderr.String())
	}
	fields := strings.Fields(strings.TrimSpace(string(out)))
	if len(fields) == 0 {
		return nil, fmt.Errorf("invalid version list output: %q", string(out))
	}
	return fields[1:], nil
}

// padding defines constraints on additional versions to pad.
//
// These constraints help restrict version padding to "reasonable" versions,
// based on heuristics such as "we never do more than 3 prereleases for a given
// version" or "we never have more than 5 patch versions" or "we can't do more
// than 10 total releases over that time period". See the field documentation
// for details.
type padding struct {
	releases int // bounds on the total number of releases
	maj      int // bounds the number of new major versions
	majmin   int // bounds the number of new major+minor versions
	patch    int // bounds the number of new patch versions
	pre      int // the number of prereleases to pad per release
}

// padVersions pads the existing version list with potential next versions, so
// that we don't have to wait an additional day to start getting reports for a
// newly tagged version.
//
// The prereleases argument may be supplied to provide a set of potential
// prerelease candidates. For example, if the program releases prereleases of
// the form "-pre.N", prereleases should be {"pre.1", "pre.2", ...}. For each
// potential next release version, the next two prerelease versions will be
// selected out of the provided set of prereleases.
func padVersions(versions []string, prereleasePatterns []string, padding padding) []string {
	versions = slices.Clone(versions)
	semver.Sort(versions)

	latestRelease := "v0.0.0"
	all := make(map[string]bool) // for de-duplicating padded versions
	for _, v := range versions {
		cv := semver.Canonical(v)
		all[cv] = true
		if semver.Prerelease(cv) == "" && semver.Compare(latestRelease, cv) < 0 {
			latestRelease = cv
		}
	}

	parsedLatest, ok := parseSemver(latestRelease)
	if !ok {
		// "can't happen", since the latest release version should always be canonical.
		panic(fmt.Sprintf("unable to parse latest release version %q", latestRelease))
	}

	// Pad the latest version only.
	//
	// This assumes that the program in question doesn't patch older releases
	// (as is the case with gopls). If that assumption ever changes, we may need
	// to apply padding to older versions as well.
	versionsToPad := []version{parsedLatest}

	var maj, min, patch int
	for _, toPad := range versionsToPad {
		for majPadding := 0; majPadding <= padding.maj; majPadding++ {
			maj = toPad.major + majPadding
			for minPadding := 0; minPadding+majPadding <= padding.majmin; minPadding++ {
				if majPadding == 0 {
					min = toPad.minor + minPadding
				} else {
					min = minPadding
				}
				for patchPadding := 0; patchPadding <= padding.patch; patchPadding++ {
					releases := majPadding + minPadding + patchPadding
					if releases == 0 || releases > padding.releases {
						continue
					}
					if majPadding == 0 && minPadding == 0 {
						patch = toPad.patch + patchPadding
					} else {
						patch = patchPadding
					}

					v := fmt.Sprintf("v%d.%d.%d", maj, min, patch)
					if all[v] {
						// This guard is future proofing: we may have seen this version
						// before if we are ever padding something other than the latest
						// version.
						continue
					}
					versions = append(versions, v)

					// We may already have prereleases at this version. Don't pad
					// additional prereleases, under the assumption that we don't
					// typically have more than padding.pre prereleases.
					nextPrerelease := 0
					for i, patt := range prereleasePatterns {
						pre := fmt.Sprintf("%s-%s", v, patt)
						if all[pre] {
							nextPrerelease = i + 1
						}
					}
					for i := nextPrerelease; i < len(prereleasePatterns) && i < padding.pre; i++ {
						pre := fmt.Sprintf("%s-%s", v, prereleasePatterns[i])
						versions = append(versions, pre)
					}
				}
			}
		}
	}

	semver.Sort(versions)
	return versions
}

// version is a parsed semantic version.
type version struct {
	major, minor, patch int
	pre                 string
}

// parseSemver attempts to parse semver components out of the provided semver
// v. If v is not valid semver in canonical form, parseSemver returns _, _, _,
// _, false.
func parseSemver(v string) (_ version, ok bool) {
	var parsed version
	v, parsed.pre, _ = strings.Cut(v, "-")
	if _, err := fmt.Sscanf(v, "v%d.%d.%d", &parsed.major, &parsed.minor, &parsed.patch); err == nil {
		ok = true
	}
	return parsed, ok
}
