// 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"
	"fmt"
	"go/format"
	"path"
	"regexp"
	"strings"
	"text/template"
	"time"

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

// 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
//
// On success, the ID of the change is returned, like "dl~1234".
func (t *VersionTasks) MailDLCL(ctx *workflow.TaskContext, versions []string, reviewers []string, dryRun bool) (changeID string, _ error) {
	if err := oneOrTwoGoVersions(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)
		ctx.Printf("file %q (command %q):\n%s", path.Join(ver, "main.go"), "golang.org/dl/"+ver, gofmted)
	}

	// Create a Gerrit CL using the Gerrit API.
	if dryRun {
		return "(dry-run)", nil
	}
	changeInput := gerrit.ChangeInput{
		Project: "dl",
		Subject: "dl: add " + strings.Join(versions, " and "),
		Branch:  "master",
	}
	return t.Gerrit.CreateAutoSubmitChange(ctx, changeInput, reviewers, files)
}

// oneOrTwoGoVersions returns true iff len(versions) is exactly 1 or 2
// and each version passes some lightweight checks that catch problems.
func oneOrTwoGoVersions(versions []string) error {
	if len(versions) < 1 || len(versions) > 2 {
		return fmt.Errorf("got %d Go versions, want 1 or 2", len(versions))
	}
	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}}")
}
`))
