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

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

import (
	"bytes"
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"

	"path/filepath"
	"regexp"
	"sort"
	"strings"
	"time"
	"unicode"

	"github.com/stamblerre/work-stats/generic"
	"github.com/stamblerre/work-stats/golang"
	"golang.org/x/build/maintner"
	"golang.org/x/build/maintner/godata"
)

var (
	milestone           = flag.String("milestone", "", "milestone associated with the release")
	filterDirs          = flag.String("dirs", "", "comma-separated list of directories that should be touched for a CL to be considered relevant")
	sinceCL             = flag.Int("cl", -1, "the gerrit change number of the first CL to include in the output. Only changes submitted more recently than 'cl' will be included.")
	project             = flag.String("project", "vscode-go", "name of the golang project")
	exclFile            = flag.String("exclude-from", "", "optional path to changelog MD file. If specified, any 'CL NNNN' occurrence in the content will cause that CL to be excluded from this tool's output.")
	semanticVersion     = flag.String("semver", "", "the semantic version of the new release")
	githubTokenFilePath = flag.String("token", "", "the absolute path to the github token file")
)

func main() {
	flag.Parse()

	if *semanticVersion == "" {
		log.Fatal("Must provide -semver.")
	}

	if *githubTokenFilePath == "" {
		log.Fatal("Must provide -token.")
	}

	var existingMD []byte
	if *exclFile != "" {
		var err error
		existingMD, err = ioutil.ReadFile(*exclFile)
		if err != nil {
			log.Fatal(err)
		}
	}

	corpus, err := godata.Get(context.Background())
	if err != nil {
		log.Fatal(err)
	}

	var dirs []string
	for _, dir := range strings.FieldsFunc(*filterDirs, func(r rune) bool {
		return unicode.IsSpace(r) || r == ','
	}) {
		dirs = append(dirs, filepath.ToSlash(dir))
	}

	ger := corpus.Gerrit()

	// Find the cutoff time for changes to include.
	start := time.Date(2020, time.August, 1, 00, 00, 00, 0, time.UTC)
	ger.ForeachProjectUnsorted(func(gp *maintner.GerritProject) error {
		if gp.Server() != "go.googlesource.com" || gp.Project() != *project {
			return nil
		}
		gp.ForeachCLUnsorted(func(cl *maintner.GerritCL) error {
			if cl.Status != "merged" {
				return nil
			}
			if *sinceCL >= 0 {
				if int(cl.Number) == *sinceCL {
					start = cl.Commit.CommitTime
				}
			} else if cl.Branch() == "release" && cl.Commit.CommitTime.After(start) {
				// Try to figure out when the last release was
				fmt.Println(cl.Commit.CommitTime)
				start = cl.Commit.CommitTime
			}
			return nil
		})
		return nil
	})

	var changes []*generic.Changelist
	cls := map[*maintner.GerritCL]bool{}
	ger.ForeachProjectUnsorted(func(gp *maintner.GerritProject) error {
		if gp.Server() != "go.googlesource.com" || gp.Project() != *project {
			return nil
		}
		gp.ForeachCLUnsorted(func(cl *maintner.GerritCL) error {
			// Only include 'master'
			if cl.Branch() != "master" {
				return nil
			}
			if cl.Status != "merged" {
				return nil
			}
			if cl.Commit.CommitTime.Before(start) {
				// Was in a previous release; not for this one.
				return nil
			}

			if bytes.Contains(existingMD, []byte(fmt.Sprintf("CL %d ", cl.Number))) {
				return nil
			}

			// Check that at least one file is in a relevant directory before
			// adding the CL.
			if len(dirs) > 0 {
				var found bool
				for _, file := range cl.Commit.Files {
					for _, dir := range dirs {
						if strings.Contains(file.File, dir) {
							found = true
							break
						}
					}
				}
				if !found {
					return nil
				}
			}
			if isGoplsChangeList(golang.GerritToGenericCL(cl)) {
				changes = append(changes, golang.GerritToGenericCL(cl))
				cls[cl] = true
			}
			return nil
		})
		return nil
	})

	fmt.Printf("# Version: %s\n\n", *semanticVersion)
	fmt.Printf("## TODO: version - ")
	now := time.Now()
	fmt.Printf("%s\n\n", now.Format("2 Jan, 2006"))
	fmt.Printf("### Changes\n\n")
	mdPrintChanges(changes, false)
	fmt.Printf("\n\n")

	fmt.Printf("### Issues\n\n")
	mdPrintIssues(changes, *milestone)
	fmt.Printf("\n\n")

	fmt.Printf("### Release comments\n\n")
	mdPrintReleaseComments(changes)
	fmt.Printf("\n\n")

	fmt.Printf("\n### Thanks\n\n")
	mdPrintContributors(cls)
}

func isGoplsChangeList(cl *generic.Changelist) bool {
	if strings.Contains(cl.Subject, "internal/lsp") || strings.Contains(cl.Subject, "gopls") {
		return true
	}
	for _, issue := range cl.AssociatedIssues {
		if issue.Repo == "golang/vscode-go" {
			return true
		}
		for _, label := range issue.Labels {
			if label == "gopls" {
				return true
			}
		}
	}
	return false
}

func mdPrintChanges(changes []*generic.Changelist, byCategory bool) {
	printChange := func(change *generic.Changelist) {
		fmt.Printf("- ")
		content := change.Subject
		note := releaseNote(change)
		if note != "" && note != "yes" && note != "y" {
			// The release note contains content.
			content = note
		}

		fmt.Printf("%s", content)
		if len(change.AssociatedIssues) > 0 {
			fmt.Printf(" (")
			for i, issue := range change.AssociatedIssues {
				if i == 0 {
					fmt.Printf("[Issue %d](https://%s)", issue.Number, issue.Link)
				} else {
					fmt.Printf(", [%d](https://%s)", issue.Number, issue.Link)
				}
			}
			fmt.Printf(")")
		}
		fmt.Printf(" <!-- CL %d -->\n", change.Number)
	}
	// Group CLs by category or by first associated issue number.
	if byCategory {
		pkgMap := map[string][]*generic.Changelist{}
		for _, change := range changes {
			pkgMap[change.Category()] = append(pkgMap[change.Category()], change)
		}
		for _, changes := range pkgMap {
			for _, change := range changes {
				printChange(change)
			}
		}
	} else {
		sort.Slice(changes, func(i, j int) bool {
			// Sort first by associated issue, then by CL number.
			var iIssue, jIssue int // first associated issues
			if len(changes[i].AssociatedIssues) > 0 {
				iIssue = changes[i].AssociatedIssues[0].Number
			}
			if len(changes[j].AssociatedIssues) > 0 {
				jIssue = changes[j].AssociatedIssues[0].Number
			}
			if iIssue != 0 && jIssue != 0 {
				return iIssue < jIssue // sort CLs with issues first
			}
			return iIssue != 0 || changes[i].Number < changes[j].Number
		})

		currentChange := -1
		for i, change := range changes {
			if len(change.AssociatedIssues) > 0 && change.AssociatedIssues[0].Number != currentChange {
				currentChange = change.AssociatedIssues[0].Number
				fmt.Printf("CL(s) for issue %d:\n", currentChange)
			} else if len(change.AssociatedIssues) == 0 && (i == 0 || len(changes[i-1].AssociatedIssues) > 0) {
				fmt.Printf("CL(s) not associated with any issue:\n")
			}
			printChange(change)
		}
	}
}

func mdPrintIssues(changes []*generic.Changelist, milestone string) {
	var issues []*generic.Issue
	for _, change := range changes {
		issues = append(issues, change.AssociatedIssues...)
	}
	sort.Slice(issues, func(i, j int) bool {
		return issues[i].Link < issues[j].Link
	})
	for _, issue := range issues {
		if !issue.Closed() {
			continue
		}
		fmt.Printf("%s: %s\n", issue.Link, issue.Milestone)
	}
}

func mdPrintReleaseComments(changes []*generic.Changelist) {
	type Issue struct {
		repo   string
		number int
	}
	printedIssues := make(map[Issue]bool)
	for _, change := range changes {
		for _, issue := range change.AssociatedIssues {
			if _, ok := printedIssues[Issue{issue.Repo, issue.Number}]; !ok {
				printedIssues[Issue{issue.Repo, issue.Number}] = true
				printIssueReleaseComment(issue.Repo, issue.Number)
			}
		}
	}
}

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

func parseRelNote(s string) string {
	if m := relNoteRx.FindStringSubmatch(s); m != nil {
		return m[1]
	}
	return ""
}

func releaseNote(cl *generic.Changelist) string {
	if strings.Contains(cl.Message, "RELNOTE") {
		return parseRelNote(cl.Message)
	}
	for _, comment := range cl.Comments {
		if strings.Contains(comment, "RELNOTE") {
			return parseRelNote(comment)
		}
	}
	return ""
}

func mdPrintContributors(cls map[*maintner.GerritCL]bool) {
	var usernames []string
	for changelist := range cls {
		author, err := fetchCLAuthorName(changelist, *project)
		if err != nil {
			log.Fatalf("Error fetching Github information for %s: %v\n", changelist.Owner(), err)
		}
		usernames = append(usernames, author)
	}
	usernames = unique(usernames)
	if len(usernames) > 1 {
		usernames[len(usernames)-1] = "and " + usernames[len(usernames)-1]
	}

	fmt.Printf("Thank you for your contribution, %s!\n", strings.Join(usernames, ", "))
}

func getURL(url string) ([]byte, error) {
	req, _ := http.NewRequest("GET", url, nil)
	if token, err := ioutil.ReadFile(*githubTokenFilePath); err == nil {
		req.Header.Set("Authorization", "token "+strings.TrimSpace(string(token)))
	}
	res, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}
	defer res.Body.Close()
	body, err := ioutil.ReadAll(res.Body)
	if err != nil {
		log.Fatalf("Error fetching Github information at %s: %v\n", url, err)
	}
	return body, nil
}

func fetchCLAuthorName(changelist *maintner.GerritCL, repo string) (string, error) {
	githubRepoMapping := map[string]string{
		"tools":     "golang/tools",
		"vscode-go": "golang/vscode-go",
	}
	body, err := getURL(fmt.Sprintf("https://api.github.com/repos/%s/commits/%s", githubRepoMapping[repo], changelist.Commit.Hash))
	if err != nil {
		return "", err
	}
	var resp map[string]interface{}
	if err := json.Unmarshal(body, &resp); err != nil {
		return "", err
	}
	if authorInfo, _ := resp["author"].(map[string]interface{}); authorInfo != nil {
		if username, ok := authorInfo["login"].(string); ok {
			return "@" + username, nil
		}
	}
	return changelist.Owner().Name(), nil
}

// printIssueReleaseComment collects the release comments, which marked by the annotation *Release*, from the issues included in this release.
func printIssueReleaseComment(repo string, issueNumber int) {
	body, err := getURL(fmt.Sprintf("https://api.github.com/repos/%s/issues/%d/comments", repo, issueNumber))
	if err != nil {
		log.Fatal(err)
	}
	var issueComments []interface{}
	if err := json.Unmarshal(body, &issueComments); err != nil {
		log.Fatalf("Error fetching Github information for issue %d:\n", issueNumber)
	}
	for _, comment := range issueComments {
		c, _ := comment.(map[string]interface{})
		if str, ok := c["body"].(string); ok && strings.Contains(str, "*Release*") {
			fmt.Println(str)
			return
		}
	}
}

// unique returns a ascendingly sorted set of unique strings among its input
func unique(input []string) []string {
	m := make(map[string]bool)
	for _, entry := range input {
		m[entry] = true
	}
	var list []string
	for key := range m {
		list = append(list, key)
	}
	sort.Strings(list)
	return list
}
