// Copyright 2020 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 (
	"bufio"
	"bytes"
	"context"
	_ "embed"
	"errors"
	"fmt"
	"regexp"
	"strconv"
	"strings"
	"text/template"
	"time"

	"cloud.google.com/go/cloudbuild/apiv1/v2/cloudbuildpb"
	"github.com/google/go-github/v74/github"
	"golang.org/x/build/gerrit"
	"golang.org/x/build/internal/relui/groups"
	"golang.org/x/build/internal/secret"
	wf "golang.org/x/build/internal/workflow"
	"golang.org/x/mod/semver"
)

// VSCode extensions and semantic versioning have different understandings of
// release and pre-release.

// From the VSCode extension guidelines:
// - Pre-releases contain the latest changes and use odd-numbered minor versions
// (e.g. v0.45.0).
// - Releases are more stable and use even-numbered minor versions (e.g.
// v0.44.0).
// See: https://code.visualstudio.com/api/working-with-extensions/publishing-extension#prerelease-extensions

// In semantic versioning:
// - Pre-releases use a hyphen and label (e.g. v0.44.0-rc.1).
// - Releases have no hyphen (e.g. v0.44.0).
// See: https://semver.org/spec/v2.0.0.html

// To avoid confusion, vscode-go release flow will use terminology below without
// overloading the term "pre-release":

// - Stable version: VSCode extension's release version (even minor, e.g. v0.44.0)
// - Insider version: VSCode extension's pre-release version (odd minor, e.g. v0.45.0)
// - Release version: Semantic versioning release (no hyphen, e.g. v0.44.0)
// - Pre-release version: Semantic versioning pre-release (with hyphen, e.g. v0.44.0-rc.1)

// ReleaseVSCodeGoTasks implements a set of vscode-go release workflow definitions.
//
// * pre-release workflow: creates a pre-release version of a stable version.
// * release workflow: creates a release version of a stable version.
// * insider workflow: creates a insider version. There are no pre-releases for
// insider versions.
type ReleaseVSCodeGoTasks struct {
	Gerrit             GerritClient
	GitHub             GitHubClientInterface
	CloudBuild         CloudBuildClient
	ApproveAction      func(*wf.TaskContext) error
	SendMail           func(*wf.TaskContext, MailHeader, MailContent) error
	AnnounceMailHeader MailHeader
}

var nextVersionParam = wf.ParamDef[string]{
	Name: "next version",
	ParamType: wf.ParamType[string]{
		HTMLElement: "select",
		HTMLSelectOptions: []string{
			"next minor",
			"next patch",
			"use explicit version",
		},
	},
}

//go:embed template/vscode-go-release-issue.md
var vscodeGoReleaseIssueTmplStr string

//go:embed template/vscode-go-changelog-entry.md
var vscodeGoChangelogEntryTmplStr string

// vscodeGoActiveReleaseBranch returns the current active release branch in
// vscode-go project.
func vscodeGoActiveReleaseBranch(ctx *wf.TaskContext, gerrit GerritClient) (string, error) {
	branches, err := gerrit.ListBranches(ctx, "vscode-go")
	if err != nil {
		return "", err
	}

	var latestMajor, latestMinor int
	active := ""
	for _, branch := range branches {
		branchName, found := strings.CutPrefix(branch.Ref, "refs/heads/")
		if !found {
			continue
		}
		majorMinor, found := strings.CutPrefix(branchName, "release-v")
		if !found {
			continue
		}
		versions := strings.Split(majorMinor, ".")
		if len(versions) != 2 {
			continue
		}

		major, err := strconv.Atoi(versions[0])
		if err != nil {
			continue
		}
		minor, err := strconv.Atoi(versions[1])
		if err != nil {
			continue
		}

		// Only consider release branch for stable versions.
		if minor%2 == 1 {
			continue
		}

		if major > latestMajor || (major == latestMajor && minor > latestMinor) {
			latestMajor = major
			latestMinor = minor
			active = branchName
		}
	}

	// "release" is the release branch before vscode-go switch multi release
	// branch model.
	if active == "" {
		active = "release"
	}

	return active, nil
}

func vscodeGoReleaseBranch(release releaseVersion) string {
	return fmt.Sprintf("release-v%v.%v", release.Major, release.Minor)
}

// NewPrereleaseDefinition create a new workflow definition for vscode-go pre-release.
func (r *ReleaseVSCodeGoTasks) NewPrereleaseDefinition() *wf.Definition {
	wd := wf.New(wf.ACL{Groups: []string{groups.ToolsTeam}})

	versionBumpStrategy := wf.Param(wd, nextVersionParam)
	coordinators := wf.Param(wd, releaseCoordinatorsParam)

	release := wf.Task1(wd, "determine the release version", r.determineReleaseVersion, versionBumpStrategy)
	prerelease := wf.Task1(wd, "find the next pre-release version", r.nextPrereleaseVersion, release)
	approved := wf.Action2(wd, "await release coordinator's approval", r.approveStablePrerelease, release, prerelease)

	branch := wf.Task2(wd, "create release branch", r.createReleaseBranch, release, prerelease, wf.After(approved))

	changeID := wf.Task2(wd, "update package.json in release branch", r.updatePackageJSONVersionInReleaseBranch, release, coordinators, wf.After(branch))
	submitted := wf.Task1(wd, "await package.json CL submission", clAwaiter{r.Gerrit}.awaitSubmission, changeID)

	// Read the head of the release branch after the required CL submission.
	revision := wf.Task2(wd, "find the revision for the pre-release version", r.Gerrit.ReadBranchHead, wf.Const("vscode-go"), branch, wf.After(submitted))
	verified := wf.Action1(wd, "verify the release candidate", r.verifyTestResults, revision)

	issue := wf.Task2(wd, "create release milestone and issue", r.createReleaseMilestoneAndIssue, release, coordinators, wf.After(verified))
	build := wf.Task3(wd, "generate package extension (.vsix) for release candidate", r.generatePackageExtension, release, prerelease, revision, wf.After(verified))

	tagged := wf.Action3(wd, "tag the release candidate", r.tag, revision, release, prerelease, wf.After(branch))
	released := wf.Action3(wd, "create release note", r.createGitHubRelease, release, prerelease, build, wf.After(tagged))

	wf.Action4(wd, "mail announcement", r.mailAnnouncement, release, prerelease, revision, issue, wf.After(released))
	return wd
}

func (r *ReleaseVSCodeGoTasks) verifyTestResults(ctx *wf.TaskContext, revision string) error {
	// We are running all tests in a docker as a user 'node' (uid: 1000)
	// Let the user own the directory.
	testScript := `#!/usr/bin/env bash
set -eux
set -o pipefail

chown -R 1000:1000 .
./build/all.bash testlocal &> output.log
`

	build, err := r.CloudBuild.RunCustomSteps(ctx, func(resultURL string) []*cloudbuildpb.BuildStep {
		return []*cloudbuildpb.BuildStep{
			{
				Name: "gcr.io/cloud-builders/git",
				Args: []string{"clone", "https://go.googlesource.com/vscode-go", "vscode-go"},
			},
			{
				Name: "gcr.io/cloud-builders/git",
				Args: []string{"checkout", revision},
				Dir:  "vscode-go",
			},
			{
				Name:   "gcr.io/cloud-builders/docker",
				Script: testScript,
				Dir:    "vscode-go",
			},
			{
				Name: "gcr.io/cloud-builders/gcloud",
				Args: []string{"storage", "cp", "output.log", fmt.Sprintf("%s/output.log", resultURL)},
				Dir:  "vscode-go",
			},
		}
	}, nil)
	if err != nil {
		return err
	}

	outputs, err := buildToOutputs(ctx, r.CloudBuild, build)
	if err != nil {
		return err
	}

	ctx.Printf("the output from test run:\n%s\n", outputs["output.log"])
	return nil
}

func (r *ReleaseVSCodeGoTasks) createReleaseMilestoneAndIssue(ctx *wf.TaskContext, semv releaseVersion, coordinators []string) (int, error) {
	version := fmt.Sprintf("v%v.%v.%v", semv.Major, semv.Minor, semv.Patch)

	// The vscode-go release milestone name matches the release version.
	milestoneID, err := r.GitHub.FetchMilestone(ctx, "golang", "vscode-go", version, true)
	if err != nil {
		return 0, err
	}

	title := fmt.Sprintf("Release %s", version)
	issues, err := r.GitHub.FetchMilestoneIssues(ctx, "golang", "vscode-go", milestoneID)
	if err != nil {
		return 0, err
	}
	for id := range issues {
		issue, _, err := r.GitHub.GetIssue(ctx, "golang", "vscode-go", id)
		if err != nil {
			return 0, err
		}
		if title == issue.GetTitle() {
			ctx.Printf("found existing releasing issue %v", id)
			return id, nil
		}
	}

	if len(coordinators) == 0 {
		return 0, fmt.Errorf("the input coordinators slice is empty")
	}
	assignee, err := lookupCoordinator(coordinators[0])
	if err != nil {
		return 0, fmt.Errorf("failed to find the coordinator %q", coordinators[0])
	}
	issue, _, err := r.GitHub.CreateIssue(ctx, "golang", "vscode-go", &github.IssueRequest{
		Title:     new(title),
		Body:      new(fmt.Sprintf(vscodeGoReleaseIssueTmplStr, version)),
		Assignee:  new(assignee.GitHub),
		Milestone: new(milestoneID),
	})
	if err != nil {
		return 0, fmt.Errorf("failed to create release tracking issue for %q: %w", version, err)
	}
	ctx.Printf("created releasing issue %v", *issue.Number)
	return *issue.Number, nil
}

// createReleaseBranch creates corresponding release branch only for the initial
// release candidate of a minor version.
func (r *ReleaseVSCodeGoTasks) createReleaseBranch(ctx *wf.TaskContext, release releaseVersion, prerelease string) (string, error) {
	branch := fmt.Sprintf("release-v%v.%v", release.Major, release.Minor)
	releaseHead, err := r.Gerrit.ReadBranchHead(ctx, "vscode-go", branch)

	if err == nil {
		ctx.Printf("Found the release branch %q with head pointing to %s\n", branch, releaseHead)
		return branch, nil
	}

	if !errors.Is(err, gerrit.ErrResourceNotExist) {
		return "", fmt.Errorf("failed to read the release branch: %w", err)
	}

	// Require vscode release branch existence if this is a non-minor release.
	if release.Patch != 0 {
		return "", fmt.Errorf("release branch is required for patch releases: %w", err)
	}

	rc, err := prereleaseNumber(prerelease)
	if err != nil {
		return "", err
	}

	// Require vscode release branch existence if this is not the first rc in
	// a minor release.
	if rc != 1 {
		return "", fmt.Errorf("release branch is required for non-initial release candidates: %w", err)
	}

	// Create the release branch using the revision from the head of master branch.
	head, err := r.Gerrit.ReadBranchHead(ctx, "vscode-go", "master")
	if err != nil {
		return "", err
	}

	ctx.DisableRetries() // Beyond this point we want retries to be done manually, not automatically.
	_, err = r.Gerrit.CreateBranch(ctx, "vscode-go", branch, gerrit.BranchInput{Revision: head})
	if err != nil {
		return "", err
	}
	ctx.Printf("Created branch %q at revision %s.\n", branch, head)
	return branch, nil
}

// generatePackageExtension builds the vscode-go package extension from source.
//
// Uses the 'revision' parameter to determine the commit to build.
// Uses the 'release' and 'prerelease' to determine the output file name.
//
// Returns a CloudBuild struct with information about the built package
// extension in Google Cloud Storage (GCS).
func (r *ReleaseVSCodeGoTasks) generatePackageExtension(ctx *wf.TaskContext, release releaseVersion, prerelease, revision string) (CloudBuild, error) {
	steps := func(resultURL string) []*cloudbuildpb.BuildStep {
		const packageScriptFmt = cloudBuildClientScriptPrefix + `
export TAG_NAME=%s

npm ci &> npm-output.log
go run tools/release/release.go package &> go-package-output.log
cat npm-output.log
cat go-package-output.log
`
		var saveScript strings.Builder
		saveScript.WriteString(cloudBuildClientScriptPrefix)
		for _, file := range []string{"npm-output.log", "go-package-output.log", vsixFileName(release, prerelease)} {
			fmt.Fprintf(&saveScript, "gcloud storage cp %s %s/%s\n", file, resultURL, file)
		}
		return []*cloudbuildpb.BuildStep{
			{
				Name:   "bash",
				Script: cloudBuildClientDownloadGoScript,
			},
			{
				Name: "gcr.io/cloud-builders/git",
				Args: []string{"clone", "https://go.googlesource.com/vscode-go", "vscode-go"},
			},
			{
				Name: "gcr.io/cloud-builders/git",
				Args: []string{"checkout", revision},
				Dir:  "vscode-go",
			},
			{
				Name:   "gcr.io/cloud-builders/npm",
				Script: fmt.Sprintf(packageScriptFmt, versionString(release, prerelease)),
				Dir:    "vscode-go/extension",
			},
			{
				Name:   "gcr.io/cloud-builders/gcloud",
				Script: saveScript.String(),
				Dir:    "vscode-go/extension",
			},
		}
	}

	build, err := r.CloudBuild.RunCustomSteps(ctx, steps, nil)
	if err != nil {
		return CloudBuild{}, err
	}

	outputs, err := buildToOutputs(ctx, r.CloudBuild, build)
	if err != nil {
		return CloudBuild{}, err
	}

	ctx.Printf("the output from npm ci:\n%s\n", outputs["npm-output.log"])
	ctx.Printf("the output from package generation:\n%s\n", outputs["go-package-output.log"])

	return build, nil
}

// publishPackageExtension generate the package extension and publish to vscode
// marketplace.
func (r *ReleaseVSCodeGoTasks) publishPackageExtension(ctx *wf.TaskContext, release releaseVersion, build CloudBuild) error {
	// Publishing to the VSCode Marketplace requires manual retries instead of
	// automatic ones.
	ctx.DisableRetries()
	steps := func(resultURL string) []*cloudbuildpb.BuildStep {
		const publishScriptFmt = cloudBuildClientScriptPrefix + `
export TAG_NAME=%s

npm ci &> npm-output.log
go run tools/release/release.go publish &> go-publish-output.log
cat npm-output.log
cat go-publish-output.log
`
		versionString := release.String()
		var saveScript strings.Builder
		saveScript.WriteString(cloudBuildClientScriptPrefix)
		for _, file := range []string{"npm-output.log", "go-publish-output.log", vsixFileName(release, "")} {
			fmt.Fprintf(&saveScript, "gcloud storage cp %s %s/%s\n", file, resultURL, file)
		}
		return []*cloudbuildpb.BuildStep{
			{
				Name:   "bash",
				Script: cloudBuildClientDownloadGoScript,
			},
			{
				Name: "gcr.io/cloud-builders/git",
				Args: []string{"clone", "https://go.googlesource.com/vscode-go", "vscode-go"},
			},
			{
				// Copy the vsix files to the vscode-go/extension directory that is the
				// default directory "go run tools/release/release.go" expects vsix
				// files to publish.
				// TODO(hxjiang): write the vsix file to a separate gcs bucket and read
				// it from there.
				Name: "gcr.io/cloud-builders/gcloud",
				Args: []string{"storage", "cp", build.ResultURL + "/" + vsixFileName(release, ""), "."},
				Dir:  "vscode-go/extension",
			},
			{
				Name:      "gcr.io/cloud-builders/npm",
				Script:    fmt.Sprintf(publishScriptFmt, versionString),
				Dir:       "vscode-go/extension",
				SecretEnv: []string{"VSCE_PAT"},
			},
			{
				Name:   "gcr.io/cloud-builders/gcloud",
				Script: saveScript.String(),
				Dir:    "vscode-go/extension",
			},
		}
	}

	build, err := r.CloudBuild.RunCustomSteps(ctx, steps, &CloudBuildOptions{
		AvailableSecrets: &cloudbuildpb.Secrets{
			SecretManager: []*cloudbuildpb.SecretManagerSecret{
				{
					VersionName: "projects/$PROJECT_ID/secrets/" + secret.NameVSCodeMarketplacePublishToken + "/versions/latest",
					Env:         "VSCE_PAT",
				},
			},
		},
	})
	if err != nil {
		return err
	}

	outputs, err := buildToOutputs(ctx, r.CloudBuild, build)
	if err != nil {
		return err
	}

	ctx.Printf("the output from npm ci:\n%s\n", outputs["npm-output.log"])
	ctx.Printf("the output from package publication:\n%s\n", outputs["go-publish-output.log"])
	return nil
}

// determineReleaseVersion determines the release version for the upcoming
// stable release of vscode-go by examining all existing tags in the repository.
//
// The versionBumpStrategy input indicates whether the pre-release should target
// the next minor or next patch version.
func (r *ReleaseVSCodeGoTasks) determineReleaseVersion(ctx *wf.TaskContext, versionBumpStrategy string) (releaseVersion, error) {
	tags, err := r.Gerrit.ListTags(ctx, "vscode-go")
	if err != nil {
		return releaseVersion{}, err
	}

	release, _ := latestVersion(tags, isReleaseVersion, isVSCodeGoStableVersion)
	switch versionBumpStrategy {
	case "next minor":
		release.Minor += 2
		release.Patch = 0
	case "next patch":
		release.Patch += 1
	default:
		return releaseVersion{}, fmt.Errorf("unknown version selection strategy: %q", versionBumpStrategy)
	}
	return release, nil
}

// nextPrereleaseVersion inspects the tags in vscode-go repo that match with the
// given version and finds the next pre-release version.
func (r *ReleaseVSCodeGoTasks) nextPrereleaseVersion(ctx *wf.TaskContext, release releaseVersion) (string, error) {
	tags, err := r.Gerrit.ListTags(ctx, "vscode-go")
	if err != nil {
		return "", err
	}

	_, prerelease := latestVersion(tags, isSameReleaseVersion(release), isPrereleaseMatchRegex(`^rc\.\d+$`))
	if prerelease == "" {
		return "rc.1", nil
	}

	pre, err := prereleaseNumber(prerelease)
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("rc.%v", pre+1), nil
}

func vsixFileName(release releaseVersion, prerelease string) string {
	// The version inside of vsix does not have prefix "v".
	return fmt.Sprintf("go-%s.vsix", versionString(release, prerelease)[1:])
}

// vscodeGoReleaseData holds data for the "vscode-go" extension release notes
// template.
type vscodeGoReleaseData struct {
	Date string

	// PreviousTag and CurrentTag are tags used to show the differences between
	// the current release and the previous one.
	PreviousTag string
	CurrentTag  string

	// Milestone is the tag containing issues for the current release.
	Milestone string

	// NextStable is the next stable version. Only used if the current release is
	// insider release.
	NextStable string

	// Body is the main content of the GitHub release notes after
	// the Git diff and milestone sections.
	Body string
}

//go:embed template/vscode-go-release-note.md
var vscodeGoReleaseNoteTmpl string

//go:embed template/vscode-go-prerelease-instructions.md
var vscodeGoPrereleaseInstallationInstructions string

// readChangeLogHeading function reads the CHANGELOG.md in vscode-go repo's
// master branch and finds the corresponding content under the heading.
func (r *ReleaseVSCodeGoTasks) readChangeLogHeading(ctx context.Context, heading string) (string, error) {
	head, err := r.Gerrit.ReadBranchHead(ctx, "vscode-go", "master")
	if err != nil {
		return "", err
	}
	source, err := r.Gerrit.ReadFile(ctx, "vscode-go", head, "CHANGELOG.md")
	if err != nil {
		return "", err
	}

	var output bytes.Buffer
	found := false

	reader := bufio.NewReader(bytes.NewReader(source))
	for {
		line, err := reader.ReadBytes('\n')
		if err != nil {
			break
		}

		// Reach to the next level 2 heading.
		if bytes.HasPrefix(line, []byte("## ")) && found {
			break
		}

		if !found && bytes.HasPrefix(line, []byte("## "+heading)) {
			found = true
			continue
		}

		if found {
			output.Write(line)
		}
	}

	return strings.TrimSpace(output.String()), nil
}

func (r *ReleaseVSCodeGoTasks) vscodeGoGitHubReleaseBody(ctx context.Context, release releaseVersion, prerelease string) (string, error) {
	baseRelease, basePrerelease, err := r.diffBaseVersion(ctx, release)
	if err != nil {
		return "", err
	}

	var data vscodeGoReleaseData
	current, previous := versionString(release, prerelease), versionString(baseRelease, basePrerelease)
	// Insider version.
	if isVSCodeGoInsiderVersion(release, prerelease) {
		var body string
		if release.Patch == 0 {
			// An insider minor version release (vX.ODD.0) is normally a dummy release
			// immediately after a stable minor version release (vX.ODD-1.0).
			// The body of the insider release will point to the corresponding stable
			// release for reference.
			const vscodeGoMinorInsiderFmt = `%s is a pre-release version identical to the official release %s, incorporating all the same bug fixes and improvements. This may include additional, experimental features that are not yet ready for general release. These features are still under development and may be subject to change or removal.

See release https://github.com/golang/vscode-go/releases/tag/%s for details.`
			body = fmt.Sprintf(vscodeGoMinorInsiderFmt, current, baseRelease, baseRelease)
		} else {
			// An insider patch version release (vX.ODD.Z Z > 0) is built from master
			// branch. The GitHub release body will be copied from the CHANGELOG.md
			// in master branch under heading ## Unreleased.
			body, err = r.readChangeLogHeading(ctx, "Unreleased")
			if err != nil {
				return "", err
			}
		}

		data = vscodeGoReleaseData{
			Date:        time.Now().Format(time.DateOnly),
			CurrentTag:  current,
			PreviousTag: previous,
			Milestone:   vscodeGoMilestone(release),
			NextStable:  releaseVersion{Major: release.Major, Minor: release.Minor + 1, Patch: 0}.String(),
			Body:        strings.TrimSpace(body),
		}
	} else {
		var body string
		if prerelease != "" {
			// For prerelease, the main body of the release will contain the
			// instructions of installation.
			body = vscodeGoPrereleaseInstallationInstructions
		} else if release.Patch == 0 {
			// The main body of the release will be copied from the CHANGELOG.md in
			// master branch under heading ## Unreleased.
			body, err = r.readChangeLogHeading(ctx, "Unreleased")
			if err != nil {
				return "", err
			}
		}

		data = vscodeGoReleaseData{
			Date:        time.Now().Format(time.DateOnly),
			CurrentTag:  current,
			PreviousTag: previous,
			Milestone:   release.String(),
			Body:        strings.TrimSpace(body),
		}
	}

	tmpl, err := template.New("vscode release").Parse(vscodeGoReleaseNoteTmpl)
	if err != nil {
		return "", err
	}

	var buf bytes.Buffer
	if err := tmpl.Execute(&buf, data); err != nil {
		return "", err
	}

	return buf.String(), nil
}

func (r *ReleaseVSCodeGoTasks) createGitHubRelease(ctx *wf.TaskContext, release releaseVersion, prerelease string, build CloudBuild) error {
	body, err := r.vscodeGoGitHubReleaseBody(ctx, release, prerelease)
	if err != nil {
		return err
	}

	versionString := versionString(release, prerelease)
	ctx.DisableRetries() // Beyond this point we want retries to be done manually, not automatically.
	draft, err := r.GitHub.CreateRelease(ctx, "golang", "vscode-go", &github.RepositoryRelease{
		TagName: new(versionString),
		Name:    new("Release " + versionString),
		Body:    new(body),
		// Both insider and release candidate are considered as prerelease.
		Prerelease: new(isVSCodeGoInsiderVersion(release, prerelease) || prerelease != ""),
		Draft:      new(true),
	})
	if err != nil {
		return err
	}
	ctx.Printf("Created the draft release note in %s", draft.GetHTMLURL())

	outFS, err := r.CloudBuild.ResultFS(ctx, build)
	if err != nil {
		return err
	}

	file, err := outFS.Open(vsixFileName(release, prerelease))
	if err != nil {
		return err
	}

	asset, err := r.GitHub.UploadReleaseAsset(ctx, "golang", "vscode-go", draft.GetID(), vsixFileName(release, prerelease), file)
	if err != nil {
		return err
	}

	ctx.Printf("Uploaded asset %s to release %v as asset ID %v", asset.GetName(), draft.GetID(), asset.GetID())

	released, err := r.GitHub.PublishRelease(ctx, "golang", "vscode-go", draft)
	if err != nil {
		return err
	}

	ctx.Printf("Published the release in %s", released.GetHTMLURL())
	return nil
}

type vscodeGoPrereleaseAnnouncement struct {
	Commit  string
	Issue   int
	Branch  string
	Version string
}

type vscodeGoReleaseAnnouncement struct {
	Version string
}

type vscodeGoInsiderAnnouncement struct {
	Commit        string
	Version       string
	StableVersion string
}

func (r *ReleaseVSCodeGoTasks) mailAnnouncement(ctx *wf.TaskContext, release releaseVersion, prerelease, revision string, issue int) error {
	var announce any
	if prerelease != "" {
		announce = vscodeGoPrereleaseAnnouncement{
			Version: versionString(release, prerelease),
			Branch:  vscodeGoReleaseBranch(release),
			Commit:  revision,
			Issue:   issue,
		}
	} else if isVSCodeGoInsiderVersion(release, prerelease) {
		announce = vscodeGoInsiderAnnouncement{
			Version:       release.String(),
			Commit:        revision,
			StableVersion: releaseVersion{Major: release.Major, Minor: release.Minor + 1, Patch: 0}.String(),
		}
	} else {
		announce = vscodeGoReleaseAnnouncement{
			Version: release.String(),
		}
	}

	content, _, err := announcementMail(announce)
	if err != nil {
		return err
	}
	ctx.Printf("announcement subject: %s\n\n", content.Subject)
	ctx.Printf("announcement body HTML:\n%s\n", content.BodyHTML)
	ctx.Printf("announcement body text:\n%s", content.BodyText)
	return r.SendMail(ctx, r.AnnounceMailHeader, content)
}

func versionString(release releaseVersion, prerelease string) string {
	version := release.String()
	if prerelease != "" {
		version += "-" + prerelease
	}
	return version
}

func (r *ReleaseVSCodeGoTasks) tag(ctx *wf.TaskContext, commit string, release releaseVersion, prerelease string) error {
	tag := versionString(release, prerelease)
	if err := r.Gerrit.Tag(ctx, "vscode-go", tag, commit); err != nil {
		return err
	}
	ctx.Printf("tagged commit %s with tag %s", commit, tag)
	return nil
}

// NewInsiderDefinition create a new workflow definition for vscode-go insider
// version release.
func (r *ReleaseVSCodeGoTasks) NewInsiderDefinition() *wf.Definition {
	wd := wf.New(wf.ACL{Groups: []string{groups.ToolsTeam}})

	reviewers := wf.Param(wd, reviewersParam)

	packageChangeID := wf.Task1(wd, "update package.json in master branch", r.updatePackageJSONVersionInMasterBranch, reviewers)
	packageSubmitted := wf.Task1(wd, "await package.json CL submission", clAwaiter{r.Gerrit}.awaitSubmission, packageChangeID)

	release := wf.Task0(wd, "determine the insider version", r.determineInsiderVersion)
	revision := wf.Task2(wd, "read the head of master branch", r.Gerrit.ReadBranchHead, wf.Const("vscode-go"), wf.Const("master"), wf.After(packageSubmitted))
	approved := wf.Action2(wd, "await release coordinator's approval", r.approveInsiderRelease, release, revision)

	verified := wf.Action1(wd, "verify the determined commit", r.verifyTestResults, revision, wf.After(approved))
	build := wf.Task3(wd, "generate package extension (.vsix) from the commit", r.generatePackageExtension, release, wf.Const(""), revision, wf.After(verified))

	tagged := wf.Action3(wd, "tag the insider release", r.tag, revision, release, wf.Const(""), wf.After(build))

	released := wf.Action3(wd, "create release note", r.createGitHubRelease, release, wf.Const(""), build, wf.After(tagged))

	changelogChangeID := wf.Task2(wd, "update CHANGELOG.md in the master branch", r.addChangeLog, release, reviewers, wf.After(tagged))
	changelogSubmitted := wf.Task1(wd, "await CHANGELOG.md CL submission", clAwaiter{r.Gerrit}.awaitSubmission, changelogChangeID)

	depsChangeID := wf.Task2(wd, "update dependencies in master branch", r.updateDependenciesIfMinor, release, reviewers, wf.After(changelogSubmitted))
	_ = wf.Task1(wd, "await dependencies CL submission", clAwaiter{r.Gerrit}.awaitSubmission, depsChangeID)

	// Publish only after the CHANGELOG.md update is merged to ensure the change
	// log reflects the latest released version.
	published := wf.Action2(wd, "publish to vscode marketplace", r.publishPackageExtension, release, build, wf.After(changelogSubmitted))

	wf.Action4(wd, "mail announcement", r.mailAnnouncement, release, wf.Const(""), revision, wf.Const(0), wf.After(released), wf.After(published))
	return wd
}

// determineInsiderVersion determines the release version for the upcoming
// insider release of vscode-go by examining all existing tags in the repository.
func (r *ReleaseVSCodeGoTasks) determineInsiderVersion(ctx *wf.TaskContext) (releaseVersion, error) {
	tags, err := r.Gerrit.ListTags(ctx, "vscode-go")
	if err != nil {
		return releaseVersion{}, err
	}

	// The insider version must be higher than the latest stable version to be
	// recognized by the marketplace.
	// VSCode automatically updates extensions to the highest available version.
	// https://code.visualstudio.com/api/working-with-extensions/publishing-extension#prerelease-extensions
	release, _ := latestVersion(tags, isReleaseVersion, isVSCodeGoStableVersion)
	major := release.Major
	minor := release.Minor + 1

	insider, _ := latestVersion(tags, isReleaseVersion, isSameMajorMinor(major, minor))
	if insider == (releaseVersion{}) {
		return releaseVersion{Major: major, Minor: minor, Patch: 0}, nil
	}
	insider.Patch += 1
	return insider, nil
}

// updatePackageJSONVersionInReleaseBranch updates the "package.json" and
// "package-lock.json" files in the release branch of the vscode-go repository.
// The "package.json" and "package-lock.json" will reference the current release
// version.
func (r *ReleaseVSCodeGoTasks) updatePackageJSONVersionInReleaseBranch(ctx *wf.TaskContext, release releaseVersion, reviewers []string) (string, error) {
	return r.updatePackageJSONVersion(ctx, vscodeGoReleaseBranch(release), release.String()[1:], reviewers)
}

// updatePackageJSONVersionInMasterBranch updates the "package.json" and
// "package-lock.json" files in the master branch of the vscode-go repository.
// The updated "package.json" and "package-lock.json" will reference the next
// stable release version with special suffix "-dev" to indicate this is a
// prerelease.
func (r *ReleaseVSCodeGoTasks) updatePackageJSONVersionInMasterBranch(ctx *wf.TaskContext, reviewers []string) (string, error) {
	tags, err := r.Gerrit.ListTags(ctx, "vscode-go")
	if err != nil {
		return "", err
	}

	latestStable, _ := latestVersion(tags, isReleaseVersion, isVSCodeGoStableVersion)
	if latestStable == (releaseVersion{}) {
		return "", fmt.Errorf("no released stable version in vscode-go")
	}

	// "package.json" in master branch should point to the next vscode-go stable
	// version with suffix "-dev". The version inside of package.json does not
	// have the prefix "v".
	// If the latest released stable version is v0.44.2, the package.json should
	// point to "0.46.0-dev".
	devVersion := versionString(releaseVersion{Major: latestStable.Major, Minor: latestStable.Minor + 2, Patch: 0}, "dev")[1:]

	return r.updatePackageJSONVersion(ctx, "master", devVersion, reviewers)
}

// updatePackageJSONVersion updates the "package.json" and "package-lock.json"
// files in the given branch of the vscode-go repository with the desired version.
func (r *ReleaseVSCodeGoTasks) updatePackageJSONVersion(ctx *wf.TaskContext, branch string, version string, reviewers []string) (string, error) {
	steps := func(resultURL string) []*cloudbuildpb.BuildStep {
		script := fmt.Sprintf(cloudBuildClientScriptPrefix+`
# Make a copy of interested files.
cp package.json package.json.before
cp package-lock.json package-lock.json.before

npm ci &> npm-output.log
npx vsce package %s --no-git-tag-version &> npx-output.log
cat npm-output.log
cat npx-output.log
`, version)

		var saveScriptFmt strings.Builder
		saveScriptFmt.WriteString(cloudBuildClientScriptPrefix)
		for _, file := range []string{
			"package.json",
			"package-lock.json",
			"package.json.before",
			"package-lock.json.before",
			"npx-output.log",
			"npm-output.log",
		} {
			fmt.Fprintf(&saveScriptFmt, "gcloud storage cp %[1]s %[2]s/%[1]s\n", file, resultURL)
		}

		return []*cloudbuildpb.BuildStep{
			{
				Name: "gcr.io/cloud-builders/git",
				Args: []string{"clone", "https://go.googlesource.com/vscode-go", "vscode-go"},
			},
			{
				Name: "gcr.io/cloud-builders/git",
				Args: []string{"checkout", branch},
				Dir:  "vscode-go",
			},
			{
				Name:   "gcr.io/cloud-builders/npm",
				Script: script,
				Dir:    "vscode-go/extension",
			},
			{
				Name:   "gcr.io/cloud-builders/gcloud",
				Script: saveScriptFmt.String(),
				Dir:    "vscode-go/extension",
			},
		}
	}

	build, err := r.CloudBuild.RunCustomSteps(ctx, steps, nil)
	if err != nil {
		return "", err
	}

	outputs, err := buildToOutputs(ctx, r.CloudBuild, build)
	if err != nil {
		return "", err
	}

	ctx.Printf("the output from npm ci:\n%s\n", outputs["npm-output.log"])
	ctx.Printf("the output from npx package:\n%s\n", outputs["npx-output.log"])

	changed := map[string]string{}
	// "npx vsce package" generate "package.json" with an offending trailing
	// new line. Remove this new line before creating the CL.
	if after := strings.TrimRight(outputs["package.json"], "\n"); after != outputs["package.json.before"] {
		changed["extension/package.json"] = after
	}
	if after := outputs["package-lock.json"]; after != outputs["package-lock.json.before"] {
		changed["extension/package-lock.json"] = after
	}

	// Skip CL creation as nothing changed.
	if len(changed) == 0 {
		ctx.Printf("package.json and package-lock.json is already up-to-date")
		return "", nil
	}

	clTitle := "extension/package.json: update version to " + version
	if branch != "master" {
		clTitle = "[" + branch + "] " + clTitle
	}
	changeID, err := r.Gerrit.CreateAutoSubmitChange(ctx, gerrit.ChangeInput{
		Project: "vscode-go",
		Branch:  branch,
		Subject: fmt.Sprintf("%s\n\nThis is an automated CL which updates the package.json and package-lock.json.\n", clTitle),
	}, reviewers, changed)
	if err != nil {
		return "", err
	}

	ctx.Printf("created auto-submit change %s under branch master in vscode-go repo.", changeID)
	return changeID, nil
}

func isVSCodeGoStableVersion(release releaseVersion, _ string) bool {
	return release.Minor%2 == 0
}

func isVSCodeGoInsiderVersion(release releaseVersion, _ string) bool {
	return release.Minor%2 == 1
}

// isReleaseVersion reports whether input version is a release version.
// (in other words, not a prerelease).
func isReleaseVersion(_ releaseVersion, prerelease string) bool {
	return prerelease == ""
}

// isPrereleaseVersion reports whether input version is a pre-release version.
// (in other words, not a release).
func isPrereleaseVersion(_ releaseVersion, prerelease string) bool {
	return prerelease != ""
}

// isPrereleaseMatchRegex reports whether the pre-release string of the input
// version matches the regex expression.
func isPrereleaseMatchRegex(regex string) func(releaseVersion, string) bool {
	return func(_ releaseVersion, prerelease string) bool {
		if prerelease == "" {
			return false
		}
		matched, err := regexp.MatchString(regex, prerelease)
		if err != nil {
			return false
		}
		return matched
	}
}

// isSameReleaseVersion reports whether the version string have the same release
// version(same major minor and patch) as input.
func isSameReleaseVersion(want releaseVersion) func(releaseVersion, string) bool {
	return func(got releaseVersion, _ string) bool {
		return got == want
	}
}

func isSameMajorMinor(major, minor int) func(releaseVersion, string) bool {
	return func(got releaseVersion, _ string) bool {
		return got.Major == major && got.Minor == minor
	}
}

// latestVersion returns the releaseVersion and the prerelease tag of the latest
// version from the provided version strings.
// It considers only versions that are valid and match all the filters.
func latestVersion(versions []string, filters ...func(releaseVersion, string) bool) (releaseVersion, string) {
	latest := ""
	latestRelease := releaseVersion{}
	latestPre := ""
	for _, v := range versions {
		release, prerelease, ok := parseVersion(v)
		if !ok {
			continue
		}

		match := true
		for _, filter := range filters {
			if !filter(release, prerelease) {
				match = false
				break
			}
		}

		if !match {
			continue
		}

		if semver.Compare(v, latest) == 1 {
			latest = v
			latestRelease = release
			latestPre = prerelease
		}
	}

	return latestRelease, latestPre
}

func (r *ReleaseVSCodeGoTasks) approveStablePrerelease(ctx *wf.TaskContext, release releaseVersion, prerelease string) error {
	ctx.Printf("The next release candidate will be %s", versionString(release, prerelease))
	return r.ApproveAction(ctx)
}

func (r *ReleaseVSCodeGoTasks) approveInsiderRelease(ctx *wf.TaskContext, release releaseVersion, commit string) error {
	// The insider version is picked from the actively developed master branch.
	// The commit information is essential for the release coordinator.
	ctx.Printf("The insider version %s will released based on commit %s", release, commit)
	ctx.Printf("See commit detail: https://go.googlesource.com/vscode-go/+/%s", commit)
	return r.ApproveAction(ctx)
}

func (r *ReleaseVSCodeGoTasks) approveStableRelease(ctx *wf.TaskContext, release releaseVersion, prerelease string) error {
	ctx.Printf("The release candidate %s will be released as %s", versionString(release, prerelease), release)
	ctx.Printf("See release candidate detail: https://go.googlesource.com/vscode-go/+/refs/tags/%s", versionString(release, prerelease))
	return r.ApproveAction(ctx)
}

// NewReleaseDefinition creates a new workflow definition for vscode-go stable
// version release.
func (r *ReleaseVSCodeGoTasks) NewReleaseDefinition() *wf.Definition {
	wd := wf.New(wf.ACL{Groups: []string{groups.ToolsTeam}})

	versionBumpStrategy := wf.Param(wd, nextVersionParam)
	reviewers := wf.Param(wd, reviewersParam)

	release := wf.Task1(wd, "determine the release version", r.determineReleaseVersion, versionBumpStrategy)
	prerelease := wf.Task1(wd, "find the latest pre-release version", r.latestPrereleaseVersion, release)

	approved := wf.Action2(wd, "await release coordinator's approval", r.approveStableRelease, release, prerelease)

	commit := wf.Task2(wd, "find the commit for the release candidate", r.findVSCodeReleaseCommit, release, prerelease, wf.After(approved))
	// Skip test result verification because it was already executed in the
	// prerelease flow.
	build := wf.Task3(wd, "generate package extension (.vsix) from release candidate tag", r.generatePackageExtension, release, wf.Const(""), commit)

	tagged := wf.Action3(wd, "tag the stable release", r.tag, commit, release, wf.Const(""), wf.After(build))
	released := wf.Action3(wd, "create release note", r.createGitHubRelease, release, wf.Const(""), build, wf.After(tagged))

	changeID := wf.Task2(wd, "update CHANGELOG.md in the master branch", r.addChangeLog, release, reviewers, wf.After(build))
	submitted := wf.Task1(wd, "await CHANGELOG.md CL submission", clAwaiter{r.Gerrit}.awaitSubmission, changeID)
	// Publish only after the CHANGELOG.md update is merged to ensure the change
	// log reflects the latest released version.
	published := wf.Action2(wd, "publish to vscode marketplace", r.publishPackageExtension, release, build, wf.After(submitted))

	wf.Action4(wd, "mail announcement", r.mailAnnouncement, release, wf.Const(""), wf.Const(""), wf.Const(0), wf.After(released), wf.After(published))
	return wd
}

// latestPrereleaseVersion inspects the tags in vscode-go repo that match with
// the given version and finds the latest pre-release version.
func (r *ReleaseVSCodeGoTasks) latestPrereleaseVersion(ctx *wf.TaskContext, release releaseVersion) (string, error) {
	tags, err := r.Gerrit.ListTags(ctx, "vscode-go")
	if err != nil {
		return "", err
	}

	_, prerelease := latestVersion(tags, isSameReleaseVersion(release), isPrereleaseMatchRegex(`^rc\.\d+$`))
	if prerelease == "" {
		return "", fmt.Errorf("could not find any release candidate for version %s", release)
	}

	return prerelease, nil
}

// findVSCodeReleaseCommit returns commit for the VS Code release candidate.
func (r *ReleaseVSCodeGoTasks) findVSCodeReleaseCommit(ctx *wf.TaskContext, release releaseVersion, prerelease string) (string, error) {
	info, err := r.Gerrit.GetTag(ctx, "vscode-go", versionString(release, prerelease))
	if err != nil {
		return "", err
	}

	return info.Revision, nil
}

// diffBaseVersion determines the appropriate base version for generating a
// commit diff against the given input version.
// The base version is selected as follows:
//   - Stable minor version(vX.EVEN.0): Latest patch of the last stable minor
//     (vX.EVEN-2.LATEST).
//   - Stable patch version(vX.Y.Z): Previous patch version (vX.Y.Z-1).
//   - Insider version(vX.ODD.Z): Last stable minor (vX.ODD-1.0-rc.1) - branch cut.
func (r *ReleaseVSCodeGoTasks) diffBaseVersion(ctx context.Context, release releaseVersion) (releaseVersion, string, error) {
	tags, err := r.Gerrit.ListTags(ctx, "vscode-go")
	if err != nil {
		return releaseVersion{}, "", err
	}

	var previousRelease releaseVersion
	var previousPrerelease string
	if isVSCodeGoInsiderVersion(release, "") {
		previousRelease = releaseVersion{Major: release.Major, Minor: release.Minor - 1, Patch: 0}
		previousPrerelease = "rc.1"
	} else {
		if release.Patch == 0 {
			previousRelease, _ = latestVersion(tags, isSameMajorMinor(release.Major, release.Minor-2), isReleaseVersion)
		} else {
			previousRelease = releaseVersion{Major: release.Major, Minor: release.Minor, Patch: release.Patch - 1}
		}
	}
	return previousRelease, previousPrerelease, nil
}

// milestoneForVersion returns the name of the github milestone associated with
// a given version.
func vscodeGoMilestone(release releaseVersion) string {
	if isVSCodeGoInsiderVersion(release, "") {
		// For insider version, the milestone will point to the next stable minor.
		// If the insider version is vX.ODD.Z, the milestone will be vX.ODD+1.0.
		return releaseVersion{Major: release.Major, Minor: release.Minor + 1, Patch: 0}.String()
	}
	return release.String()
}

// addChangeLog updates the CHANGELOG.md file in the master branch of the
// vscode-go repository with a new heading for the released version.
// For stable minor version, it moves all content from the "Unreleased" section
// to the new version's section.
// For stable patch version and insider version, add a new heading with
// pre-defined content.
// For more details on changelog format, see: https://keepachangelog.com/en/1.1.0/
func (r *ReleaseVSCodeGoTasks) addChangeLog(ctx *wf.TaskContext, release releaseVersion, reviewers []string) (string, error) {
	head, err := r.Gerrit.ReadBranchHead(ctx, "vscode-go", "master")
	if err != nil {
		return "", err
	}

	content, err := r.Gerrit.ReadFile(ctx, "vscode-go", head, "CHANGELOG.md")
	if err != nil {
		return "", err
	}

	lines := bytes.Split(content, []byte("\n"))
	var output bytes.Buffer

	if release.Patch == 0 && isVSCodeGoStableVersion(release, "") {
		for i, line := range lines {
			output.Write(line)
			// Only add a newline if it's not the last line
			if i < len(lines)-1 {
				output.WriteString("\n")
			}
			if string(line) == "## Unreleased" {
				output.WriteString("\n")
				output.WriteString("## " + release.String() + "\n")
				output.WriteString("\n")
				output.WriteString("Date: " + time.Now().Format(time.DateOnly) + "\n")
			}
		}
	} else {
		entryAdded := false
		for i, line := range lines {
			if !entryAdded && bytes.HasPrefix(line, []byte("## ")) && string(line) != "## Unreleased" {
				entryAdded = true
				baseRelease, basePrerelease, err := r.diffBaseVersion(ctx, release)
				if err != nil {
					return "", err
				}

				data := map[string]string{
					"Current":   release.String(),
					"Date":      time.Now().Format(time.DateOnly),
					"Previous":  versionString(baseRelease, basePrerelease),
					"Milestone": vscodeGoMilestone(release),
				}

				if isVSCodeGoInsiderVersion(release, "") {
					data["NextStable"] = fmt.Sprintf("v%v.%v", release.Major, release.Minor+1)
					data["IsPrerelease"] = "true"
				}

				tmpl, err := template.New("vscode release").Parse(vscodeGoChangelogEntryTmplStr)
				if err != nil {
					return "", err
				}

				if err := tmpl.Execute(&output, data); err != nil {
					return "", err
				}
			}
			output.Write(line)
			// Only add a newline if it's not the last line
			if i < len(lines)-1 {
				output.WriteString("\n")
			}
		}
	}

	clTitle := "CHANGELOG.md: add release heading for " + release.String()
	cl, err := r.Gerrit.CreateAutoSubmitChange(ctx, gerrit.ChangeInput{
		Project: "vscode-go",
		Branch:  "master",
		Subject: fmt.Sprintf("%s\n\nThis is an automated CL which updates the CHANGELOG.md.\n", clTitle),
	}, reviewers, map[string]string{"CHANGELOG.md": output.String()})
	if err != nil {
		return "", err
	}

	ctx.Printf("created auto-submit change %s under branch master in vscode-go repo.", cl)
	return cl, nil
}

// updateDependenciesIfMinor updates Go module dependencies in the master branch
// of vscode-go following a minor insider version release.
func (r *ReleaseVSCodeGoTasks) updateDependenciesIfMinor(ctx *wf.TaskContext, release releaseVersion, reviewers []string) (string, error) {
	if minor := release.Patch == 0; !minor || !isVSCodeGoInsiderVersion(release, "") {
		return "", nil
	}

	const script = `go get -u work && go mod tidy
(cd docs && go get -u work && go mod tidy)
(cd extension && go get -u work && go mod tidy)
(cd survey && go get -u work && go mod tidy)
`
	watchFiles := []string{
		"go.mod", "go.sum",
		"docs/go.mod", "docs/go.sum",
		"extension/go.mod", "extension/go.sum",
		"survey/go.mod", "survey/go.sum",
	}

	changed, err := executeAndMonitorChange(ctx, r.CloudBuild, "vscode-go", "master", script, watchFiles)
	if err != nil {
		return "", err
	}

	if len(changed) == 0 {
		ctx.Printf("No dependencies needed updating.")
		return "", nil
	}

	clTitle := fmt.Sprintf("go.mod: update dependencies following the %s release", release)
	changeInput := gerrit.ChangeInput{
		Project: "vscode-go",
		Branch:  "master",
		Subject: fmt.Sprintf("%s\n\nThis is an automated CL which updates the go.mod and go.sum.\n", clTitle),
	}

	ctx.Printf("creating auto-submit change under master branch in vscode-go repo.")
	return r.Gerrit.CreateAutoSubmitChange(ctx, changeInput, reviewers, changed)
}
