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

import (
	"context"
	"fmt"
	"strconv"
	"strings"
	"time"

	"golang.org/x/build/buildlet"
	"golang.org/x/build/gerrit"
	"golang.org/x/build/internal/workflow"
)

// VersionTasks contains tasks related to versioning the release.
type VersionTasks struct {
	Gerrit           GerritClient
	GerritURL        string
	GoProject        string
	CreateBuildlet   func(context.Context, string) (buildlet.RemoteClient, error)
	LatestGoBinaries func(context.Context) (string, error)
}

// GetCurrentMajor returns the most recent major Go version, and the time at
// which its tag was created.
func (t *VersionTasks) GetCurrentMajor(ctx context.Context) (int, time.Time, error) {
	_, currentMajor, currentMajorTag, err := t.tagInfo(ctx)
	if err != nil {
		return 0, time.Time{}, err
	}
	info, err := t.Gerrit.GetTag(ctx, t.GoProject, currentMajorTag)
	if err != nil {
		return 0, time.Time{}, err
	}
	return currentMajor, info.Created.Time(), nil
}

func (t *VersionTasks) tagInfo(ctx context.Context) (tags map[string]bool, currentMajor int, currentMajorTag string, _ error) {
	tagList, err := t.Gerrit.ListTags(ctx, t.GoProject)
	if err != nil {
		return nil, 0, "", err
	}
	tags = map[string]bool{}
	for _, tag := range tagList {
		tags[tag] = true
	}
	// Find the most recently released major version.
	// Going down from a high number is convenient for testing.
	currentMajor = 100
	for ; ; currentMajor-- {
		base := fmt.Sprintf("go1.%d", currentMajor)
		// Handle either go1.20 or go1.21.0
		for _, tag := range []string{base, base + ".0"} {
			if tags[tag] {
				return tags, currentMajor, tag, nil
			}
		}
	}
}

// GetNextVersions returns the next for each of the given types of release.
func (t *VersionTasks) GetNextVersions(ctx context.Context, kinds []ReleaseKind) ([]string, error) {
	var next []string
	for _, k := range kinds {
		n, err := t.GetNextVersion(ctx, k)
		if err != nil {
			return nil, err
		}
		next = append(next, n)
	}
	return next, nil
}

// GetNextVersion returns the next for the given type of release.
func (t *VersionTasks) GetNextVersion(ctx context.Context, kind ReleaseKind) (string, error) {
	tags, currentMajor, _, err := t.tagInfo(ctx)
	if err != nil {
		return "", err
	}
	findUnused := func(v string) (string, error) {
		for {
			if !tags[v] {
				return v, nil
			}
			v, err = nextVersion(v)
			if err != nil {
				return "", err
			}
		}
	}
	switch kind {
	case KindCurrentMinor:
		return findUnused(fmt.Sprintf("go1.%d.1", currentMajor))
	case KindPrevMinor:
		return findUnused(fmt.Sprintf("go1.%d.1", currentMajor-1))
	case KindBeta:
		return findUnused(fmt.Sprintf("go1.%dbeta1", currentMajor+1))
	case KindRC:
		return findUnused(fmt.Sprintf("go1.%drc1", currentMajor+1))
	case KindMajor:
		return fmt.Sprintf("go1.%d.0", currentMajor+1), nil
	}
	return "", fmt.Errorf("unknown release kind %v", kind)
}

func nextVersion(version string) (string, error) {
	lastNonDigit := strings.LastIndexFunc(version, func(r rune) bool {
		return r < '0' || r > '9'
	})
	if lastNonDigit == -1 || len(version) == lastNonDigit {
		return "", fmt.Errorf("malformatted Go version %q", version)
	}
	n, err := strconv.Atoi(version[lastNonDigit+1:])
	if err != nil {
		return "", fmt.Errorf("malformatted Go version %q (%v)", version, err)
	}
	return fmt.Sprintf("%s%d", version[:lastNonDigit+1], n+1), nil
}

func (t *VersionTasks) GenerateVersionFile(_ *workflow.TaskContext, distpack bool, version string, timestamp time.Time) (string, error) {
	if !distpack {
		return version, nil
	}
	return fmt.Sprintf("%v\ntime %v\n", version, timestamp.Format(time.RFC3339)), nil
}

// CreateAutoSubmitVersionCL mails an auto-submit change to update VERSION on branch.
func (t *VersionTasks) CreateAutoSubmitVersionCL(ctx *workflow.TaskContext, branch string, reviewers []string, versionFile string) (string, error) {
	return t.Gerrit.CreateAutoSubmitChange(ctx, gerrit.ChangeInput{
		Project: t.GoProject,
		Branch:  branch,
		Subject: fmt.Sprintf("[%v] %v", branch, versionFile),
	}, reviewers, map[string]string{
		"VERSION": versionFile,
	})
}

// AwaitCL waits for the specified CL to be submitted, and returns the new
// branch head. Callers can pass baseCommit, the current branch head, to verify
// that no CLs were submitted between when the CL was created and when it was
// merged. If changeID is blank because the intended CL was a no-op, baseCommit
// is returned immediately.
func (t *VersionTasks) AwaitCL(ctx *workflow.TaskContext, changeID, baseCommit string) (string, error) {
	if changeID == "" {
		ctx.Printf("No CL was necessary")
		return baseCommit, nil
	}

	ctx.Printf("Awaiting review/submit of %v", ChangeLink(changeID))
	return AwaitCondition(ctx, 10*time.Second, func() (string, bool, error) {
		return t.Gerrit.Submitted(ctx, changeID, baseCommit)
	})
}

// ReadBranchHead returns the current HEAD revision of branch.
func (t *VersionTasks) ReadBranchHead(ctx *workflow.TaskContext, branch string) (string, error) {
	return t.Gerrit.ReadBranchHead(ctx, t.GoProject, branch)
}

// TagRelease tags commit as version.
func (t *VersionTasks) TagRelease(ctx *workflow.TaskContext, version, commit string) error {
	return t.Gerrit.Tag(ctx, t.GoProject, version, commit)
}

func (t *VersionTasks) CreateUpdateStdlibIndexCL(ctx *workflow.TaskContext, reviewers []string, version string) (string, error) {
	var files = make(map[string]string) // Map key is relative path, and map value is file content.

	binaries, err := t.LatestGoBinaries(ctx)
	if err != nil {
		return "", err
	}
	bc, err := t.CreateBuildlet(ctx, "linux-amd64-longtest")
	if err != nil {
		return "", err
	}
	defer bc.Close()
	if err := bc.PutTarFromURL(ctx, binaries, ""); err != nil {
		return "", err
	}
	toolsTarURL := fmt.Sprintf("%s/%s/+archive/%s.tar.gz", t.GerritURL, "tools", "master")
	if err := bc.PutTarFromURL(ctx, toolsTarURL, "tools"); err != nil {
		return "", err
	}
	writer := &LogWriter{Logger: ctx}
	go writer.Run(ctx)
	remoteErr, execErr := bc.Exec(ctx, "go/bin/go", buildlet.ExecOpts{
		Dir:    "tools",
		Args:   []string{"generate", "./internal/imports"},
		Output: writer,
	})
	if execErr != nil {
		return "", fmt.Errorf("Exec failed: %v", execErr)
	}
	if remoteErr != nil {
		return "", fmt.Errorf("Command failed: %v", remoteErr)
	}
	tgz, err := bc.GetTar(context.Background(), "tools/internal/imports")
	if err != nil {
		return "", err
	}
	defer tgz.Close()
	tools, err := tgzToMap(tgz)
	if err != nil {
		return "", err
	}
	files["internal/imports/zstdlib.go"] = tools["zstdlib.go"]

	changeInput := gerrit.ChangeInput{
		Project: "tools",
		Subject: fmt.Sprintf("internal/imports: update stdlib index for %s\n\nFor golang/go#38706.", strings.Replace(version, "go", "Go ", 1)),
		Branch:  "master",
	}
	return t.Gerrit.CreateAutoSubmitChange(ctx, changeInput, reviewers, files)
}
