// Copyright 2017 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.

//go:build go1.21

// The relnote command summarizes the Go changes in Gerrit marked with
// RELNOTE annotations for the release notes.
package main

import (
	"bytes"
	"context"
	"flag"
	"fmt"
	"html"
	"log"
	"os"
	"path"
	"path/filepath"
	"regexp"
	"runtime"
	"slices"
	"sort"
	"strconv"
	"strings"
	"time"

	"golang.org/x/build/gerrit"
	"golang.org/x/build/maintner"
	"golang.org/x/build/maintner/godata"
	"golang.org/x/build/repos"
)

var verbose = flag.Bool("v", false, "print verbose logging")

// change is a change that was noted via a RELNOTE= comment.
type change struct {
	CL    *maintner.GerritCL
	Note  string // the part after RELNOTE=
	Issue *maintner.GitHubIssue
}

func (c change) ID() string {
	switch {
	default:
		panic("invalid change")
	case c.CL != nil:
		return fmt.Sprintf("CL %d", c.CL.Number)
	case c.Issue != nil:
		return fmt.Sprintf("https://go.dev/issue/%d", c.Issue.Number)
	}
}

func (c change) URL() string {
	switch {
	default:
		panic("invalid change")
	case c.CL != nil:
		return fmt.Sprint("https://go.dev/cl/", c.CL.Number)
	case c.Issue != nil:
		return fmt.Sprint("https://go.dev/issue/", c.Issue.Number)
	}
}

func (c change) Subject() string {
	switch {
	default:
		panic("invalid change")
	case c.CL != nil:
		subj := c.CL.Subject()
		subj = strings.TrimPrefix(subj, clPackage(c.CL)+":")
		return strings.TrimSpace(subj)
	case c.Issue != nil:
		return issueSubject(c.Issue)
	}
}

func (c change) TextLine() string {
	switch {
	default:
		panic("invalid change")
	case c.CL != nil:
		subj := c.CL.Subject()
		if c.Note != "yes" && c.Note != "y" {
			subj += "; " + c.Note
		}
		return subj
	case c.Issue != nil:
		return issueSubject(c.Issue)
	}
}

func usage() {
	out := flag.CommandLine.Output()
	fmt.Fprintf(out, "usage:\n")
	fmt.Fprintf(out, "   relnote\n")
	fmt.Fprintf(out, "      summarize the Go changes in Gerrit marked with\n")
	fmt.Fprintf(out, "      RELNOTE annotations for the release notes (obsolete)\n")
	fmt.Fprintf(out, "   relnote generate [GOROOT]\n")
	fmt.Fprintf(out, "      generate release notes from doc/next under GOROOT (default: runtime.GOROOT())\n")
	fmt.Fprintf(out, "   relnote todo\n")
	fmt.Fprintf(out, "      report which release notes need to be written\n")
	flag.PrintDefaults()
}

func main() {
	log.SetPrefix("relnote: ")
	log.SetFlags(0)
	flag.Usage = usage
	flag.Parse()

	goroot := runtime.GOROOT()
	if goroot == "" {
		log.Fatalf("missing GOROOT")
	}

	// Read internal/goversion to find the next release.
	data, err := os.ReadFile(filepath.Join(goroot, "src/internal/goversion/goversion.go"))
	if err != nil {
		log.Fatal(err)
	}
	m := regexp.MustCompile(`Version = (\d+)`).FindStringSubmatch(string(data))
	if m == nil {
		log.Fatalf("cannot find Version in src/internal/goversion/goversion.go")
	}
	version := m[1]

	// Dispatch to a subcommand if one is provided.
	if cmd := flag.Arg(0); cmd != "" {
		switch cmd {
		case "generate":
			err = generate(version, flag.Arg(1))
		case "todo":
			nextDir := filepath.Join(goroot, "doc", "next")
			err = todo(os.Stdout, os.DirFS(nextDir))
		default:
			err = fmt.Errorf("unknown command %q", cmd)
		}
		if err != nil {
			log.Fatal(err)
		}
		return
	}

	// Releases are every 6 months. Walk forward by 6 month increments to next release.
	cutoff := time.Date(2016, time.August, 1, 00, 00, 00, 0, time.UTC)
	now := time.Now()
	for cutoff.Before(now) {
		cutoff = cutoff.AddDate(0, 6, 0)
	}

	// Previous release was 6 months earlier.
	cutoff = cutoff.AddDate(0, -6, 0)

	// The maintner corpus doesn't track inline comments. See go.dev/issue/24863.
	// So we need to use a Gerrit API client to fetch them instead. If maintner starts
	// tracking inline comments in the future, this extra complexity can be dropped.
	gerritClient := gerrit.NewClient("https://go-review.googlesource.com", gerrit.NoAuth)
	matchedCLs, err := findCLsWithRelNote(gerritClient, cutoff)
	if err != nil {
		log.Fatal(err)
	}

	existingHTML, err := os.ReadFile(filepath.Join(goroot, "doc/go1."+version+".html"))
	if err != nil {
		log.Fatal(err)
	}

	corpus, err := godata.Get(context.Background())
	if err != nil {
		log.Fatal(err)
	}
	changes := map[string][]change{} // keyed by pkg
	unclosed := map[int32][]int32{}  // from issue number to CL numbers
	gh := corpus.GitHub().Repo("golang", "go")
	addedIssue := make(map[int32]bool)
	corpus.Gerrit().ForeachProjectUnsorted(func(gp *maintner.GerritProject) error {
		if gp.Server() != "go.googlesource.com" {
			return nil
		}
		gp.ForeachCLUnsorted(func(cl *maintner.GerritCL) error {
			if cl.Status != "merged" {
				return nil
			}
			if cl.Branch() != "master" {
				// Ignore CLs sent to development or release branches.
				return nil
			}
			if cl.Commit.CommitTime.Before(cutoff) {
				// Was in a previous release; not for this one.
				return nil
			}
			for _, num := range issueNumbers(cl) {
				if bytes.Contains(existingHTML, []byte(fmt.Sprintf("https://go.dev/issue/%d", num))) || addedIssue[num] {
					continue
				}
				if issue := gh.Issue(num); issue != nil && hasLabel(issue, "Proposal-Accepted") {
					if *verbose {
						log.Printf("CL %d mentions accepted proposal #%d (%s)", cl.Number, num, issue.Title)
					}
					if !issue.ClosedAt.Before(cutoff) {
						pkg := issuePackage(issue)
						changes[pkg] = append(changes[pkg], change{Issue: issue})
						addedIssue[num] = true
					} else if !issue.Closed {
						unclosed[num] = append(unclosed[num], cl.Number)
					}
				}
			}

			if bytes.Contains(existingHTML, []byte(fmt.Sprintf("CL %d", cl.Number))) {
				return nil
			}
			var relnote string
			if _, ok := matchedCLs[int(cl.Number)]; ok {
				comments, err := gerritClient.ListChangeComments(context.Background(), fmt.Sprint(cl.Number))
				if err != nil {
					return err
				}
				relnote = clRelNote(cl, comments)
			}
			if relnote == "" {
				// Invent a RELNOTE=modified api/name.txt if the commit modifies any API files.
				var api []string
				for _, f := range cl.Commit.Files {
					if strings.HasPrefix(f.File, "api/") && strings.HasSuffix(f.File, ".txt") {
						api = append(api, f.File)
					}
				}
				if len(api) > 0 {
					relnote = "modified " + strings.Join(api, ", ")
					if *verbose {
						log.Printf("CL %d %s", cl.Number, relnote)
					}
				}
			}
			if relnote != "" {
				pkg := clPackage(cl)
				changes[pkg] = append(changes[pkg], change{
					Note: relnote,
					CL:   cl,
				})
			}
			return nil
		})
		return nil
	})

	var pkgs []string
	for pkg, changes := range changes {
		pkgs = append(pkgs, pkg)
		sort.Slice(changes, func(i, j int) bool {
			x, y := &changes[i], &changes[j]
			if (x.Issue != nil) != (y.Issue != nil) {
				return x.Issue != nil
			}
			if x.Issue != nil {
				return x.Issue.Number < y.Issue.Number
			}
			return x.CL.Number < y.CL.Number
		})
	}
	sort.Strings(pkgs)

	// TODO(rsc): Instead of making people do the mechanical work of
	// copy and pasting this TODO HTML into the release notes,
	// relnote should edit the release notes directly to insert the TODOs.
	// Then it should print to standard output only a summary of the
	// changes it made.
	for _, pkg := range pkgs {
		if !strings.HasPrefix(pkg, "cmd/") {
			continue
		}
		for _, change := range changes[pkg] {
			fmt.Printf("<!-- %s -->\n<p>\n  <!-- %s -->\n</p>\n", change.ID(), change.TextLine())
		}
	}
	for _, pkg := range pkgs {
		if strings.HasPrefix(pkg, "cmd/") {
			continue
		}
		fmt.Printf("\n<dl id=%q><dt><a href=%q>%s</a></dt>\n  <dd>",
			pkg, "/pkg/"+pkg+"/", pkg)
		for _, change := range changes[pkg] {
			fmt.Printf("\n    <p><!-- %s -->\n      TODO: <a href=%q>%s</a>: %s\n    </p>\n",
				change.ID(), change.URL(), change.URL(), html.EscapeString(change.TextLine()))
		}
		fmt.Printf("  </dd>\n</dl><!-- %s -->\n", pkg)
	}
	for issue, cls := range unclosed {
		var s []string
		for _, cl := range cls {
			s = append(s, strconv.Itoa(int(cl)))
		}
		fmt.Fprintf(os.Stderr, "Warning: accepted proposal #%d is not closed but has these CLs: %s\n", issue, strings.Join(s, ", "))
	}
}

// findCLsWithRelNote finds CLs that contain a RELNOTE marker by
// using a Gerrit API client. Returned map is keyed by CL number.
func findCLsWithRelNote(client *gerrit.Client, since time.Time) (map[int]*gerrit.ChangeInfo, error) {
	// Gerrit search operators are documented at
	// https://gerrit-review.googlesource.com/Documentation/user-search.html#search-operators.
	query := fmt.Sprintf(`status:merged branch:master since:%s (comment:"RELNOTE" OR comment:"RELNOTES")`,
		since.Format("2006-01-02"))
	cs, err := client.QueryChanges(context.Background(), query)
	if err != nil {
		return nil, err
	}
	m := make(map[int]*gerrit.ChangeInfo) // CL Number → CL.
	for _, c := range cs {
		m[c.ChangeNumber] = c
	}
	return m, nil
}

// packagePrefix returns the package prefix at the start of s.
// For example packagePrefix("net/http: add HTTP 5 support") == "net/http".
// If there's no package prefix, packagePrefix returns "".
func packagePrefix(s string) string {
	i := strings.Index(s, ":")
	if i < 0 {
		return ""
	}
	s = s[:i]
	if strings.Trim(s, "abcdefghijklmnopqrstuvwxyz0123456789/") != "" {
		return ""
	}
	return s
}

// clPackage returns the package import path from the CL's commit message,
// or "??" if it's formatted unconventionally.
func clPackage(cl *maintner.GerritCL) string {
	pkg := packagePrefix(cl.Subject())
	if pkg == "" {
		return "??"
	}
	if r := repos.ByGerritProject[cl.Project.Project()]; r == nil {
		return "??"
	} else {
		pkg = path.Join(r.ImportPath, pkg)
	}
	return pkg
}

// clRelNote extracts a RELNOTE note from a Gerrit CL commit
// message and any inline comments. If there isn't a RELNOTE
// note, it returns the empty string.
func clRelNote(cl *maintner.GerritCL, comments map[string][]gerrit.CommentInfo) string {
	msg := cl.Commit.Msg
	if strings.Contains(msg, "RELNOTE") {
		return parseRelNote(msg)
	}
	// Since July 2020, Gerrit UI has replaced top-level comments
	// with patchset-level inline comments, so don't bother looking
	// for RELNOTE= in cl.Messages—there won't be any. Instead, do
	// look through all inline comments that we got via Gerrit API.
	for _, cs := range comments {
		for _, c := range cs {
			if strings.Contains(c.Message, "RELNOTE") {
				return parseRelNote(c.Message)
			}
		}
	}
	return ""
}

// parseRelNote parses a RELNOTE annotation from the string s.
// It returns the empty string if no such annotation exists.
func parseRelNote(s string) string {
	m := relNoteRx.FindStringSubmatch(s)
	if m == nil {
		return ""
	}
	return m[1]
}

var relNoteRx = regexp.MustCompile(`RELNOTES?=(.+)`)

// issuePackage returns the package import path from the issue's title,
// or "??" if it's formatted unconventionally.
func issuePackage(issue *maintner.GitHubIssue) string {
	pkg := packagePrefix(issue.Title)
	if pkg == "" {
		return "??"
	}
	return pkg
}

// issueSubject returns the issue's title with the package prefix removed.
func issueSubject(issue *maintner.GitHubIssue) string {
	pkg := packagePrefix(issue.Title)
	if pkg == "" {
		return issue.Title
	}
	return strings.TrimSpace(strings.TrimPrefix(issue.Title, pkg+":"))
}

func hasLabel(issue *maintner.GitHubIssue, label string) bool {
	for _, l := range issue.Labels {
		if l.Name == label {
			return true
		}
	}
	return false
}

var numbersRE = regexp.MustCompile(`(?m)(?:^|\s|golang/go)#([0-9]{3,})`)
var golangGoNumbersRE = regexp.MustCompile(`(?m)golang/go#([0-9]{3,})`)

// issueNumbers returns the golang/go issue numbers referred to by the CL.
func issueNumbers(cl *maintner.GerritCL) []int32 {
	var re *regexp.Regexp
	if cl.Project.Project() == "go" {
		re = numbersRE
	} else {
		re = golangGoNumbersRE
	}

	var list []int32
	for _, s := range re.FindAllStringSubmatch(cl.Commit.Msg, -1) {
		if n, err := strconv.Atoi(s[1]); err == nil && n < 1e9 {
			list = append(list, int32(n))
		}
	}
	// Remove duplicates.
	slices.Sort(list)
	return slices.Compact(list)
}
