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, err := t.tagInfo(ctx)
	if err != nil {
		return 0, time.Time{}, err
	}
	info, err := t.Gerrit.GetTag(ctx, t.GoProject, fmt.Sprintf("go1.%d", currentMajor))
	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, _ 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-- {
		if tags[fmt.Sprintf("go1.%d", currentMajor)] {
			break
		}
	}
	return tags, currentMajor, 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", 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
}

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

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