// Copyright 2021 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 (
	"bytes"
	"context"
	"fmt"
	"go/format"
	"path"
	"regexp"
	"strings"
	"text/template"
	"time"

	"golang.org/x/build/buildenv"
	"golang.org/x/build/gerrit"
	"golang.org/x/build/internal/secret"
)

// MailDLCL mails a golang.org/dl CL that adds commands for the
// specified Go versions. It accepts one or two versions only.
//
// The versions must use the same format as Go tags. For example:
// 	• "go1.17.2" and "go1.16.9" for a minor Go release
// 	• "go1.18" for a major Go release
// 	• "go1.18beta1" or "go1.18rc1" for a pre-release
//
// Credentials are fetched from Secret Manager.
// On success, the URL of the change is returned, like "https://go.dev/cl/123".
func MailDLCL(ctx context.Context, versions []string) (changeURL string, _ error) {
	if len(versions) < 1 || len(versions) > 2 {
		return "", fmt.Errorf("got %d Go versions, want 1 or 2", len(versions))
	}
	if err := verifyGoVersions(versions...); err != nil {
		return "", err
	}

	var files = make(map[string]string) // Map key is relative path, and map value is file content.

	// Generate main.go files for versions from the template.
	for _, ver := range versions {
		var buf bytes.Buffer
		versionNoPatch, err := versionNoPatch(ver)
		if err != nil {
			return "", err
		}
		if err := dlTmpl.Execute(&buf, struct {
			Year                int
			Version             string // "go1.5.3rc2"
			VersionNoPatch      string // "go1.5"
			CapitalSpaceVersion string // "Go 1.5"
			DocHost             string // "go.dev" or "tip.golang.org" for rc/beta
		}{
			Year:                time.Now().UTC().Year(),
			Version:             ver,
			VersionNoPatch:      versionNoPatch,
			DocHost:             docHost(ver),
			CapitalSpaceVersion: strings.Replace(ver, "go", "Go ", 1),
		}); err != nil {
			return "", fmt.Errorf("dlTmpl.Execute: %v", err)
		}
		gofmted, err := format.Source(buf.Bytes())
		if err != nil {
			return "", fmt.Errorf("could not gofmt: %v", err)
		}
		files[path.Join(ver, "main.go")] = string(gofmted)
	}

	// Create a Gerrit CL using the Gerrit API.
	gobot, err := gobot()
	if err != nil {
		return "", err
	}
	ci, err := gobot.CreateChange(ctx, gerrit.ChangeInput{
		Project: "dl",
		Subject: "dl: add " + strings.Join(versions, " and "),
		Branch:  "master",
	})
	if err != nil {
		return "", err
	}
	changeID := fmt.Sprintf("%s~%d", ci.Project, ci.ChangeNumber)
	for path, content := range files {
		err := gobot.ChangeFileContentInChangeEdit(ctx, changeID, path, content)
		if err != nil {
			return "", err
		}
	}
	err = gobot.PublishChangeEdit(ctx, changeID)
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("https://go.dev/cl/%d", ci.ChangeNumber), nil
}

func verifyGoVersions(versions ...string) error {
	for _, ver := range versions {
		if ver != strings.ToLower(ver) {
			return fmt.Errorf("version %q is not lowercase", ver)
		} else if strings.Contains(ver, " ") {
			return fmt.Errorf("version %q contains a space", ver)
		} else if !strings.HasPrefix(ver, "go") {
			return fmt.Errorf("version %q doesn't have the 'go' prefix", ver)
		}
	}
	return nil
}

func docHost(ver string) string {
	if strings.Contains(ver, "rc") || strings.Contains(ver, "beta") {
		return "tip.golang.org"
	}
	return "go.dev"
}

func versionNoPatch(ver string) (string, error) {
	rx := regexp.MustCompile(`^(go\d+\.\d+)($|[\.]?\d*)($|rc|beta|\.)`)
	m := rx.FindStringSubmatch(ver)
	if m == nil {
		return "", fmt.Errorf("unrecognized version %q", ver)
	}
	if m[2] != "" {
		return "devel/release#" + m[1] + ".minor", nil
	}
	return m[1], nil
}

var dlTmpl = template.Must(template.New("").Parse(`// Copyright {{.Year}} 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.

// The {{.Version}} command runs the go command from {{.CapitalSpaceVersion}}.
//
// To install, run:
//
//     $ go install golang.org/dl/{{.Version}}@latest
//     $ {{.Version}} download
//
// And then use the {{.Version}} command as if it were your normal go
// command.
//
// See the release notes at https://{{.DocHost}}/doc/{{.VersionNoPatch}}.
//
// File bugs at https://go.dev/issue/new.
package main

import "golang.org/dl/internal/version"

func main() {
	version.Run("{{.Version}}")
}
`))

// gobot creates an authenticated Gerrit API client
// that uses the gobot@golang.org Gerrit account.
func gobot() (*gerrit.Client, error) {
	sc, err := secret.NewClientInProject(buildenv.Production.ProjectName)
	if err != nil {
		return nil, err
	}
	defer sc.Close()
	token, err := sc.Retrieve(context.Background(), secret.NameGobotPassword)
	if err != nil {
		return nil, err
	}
	return gerrit.NewClient("https://go-review.googlesource.com", gerrit.BasicAuth("git-gobot.golang.org", token)), nil
}
