// Copyright 2024 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 main

import (
	"fmt"
	"log"
	"regexp"
	"sort"
	"strings"

	"golang.org/x/build/cmd/watchflakes/internal/script"
	"rsc.io/github"
)

// An Issue is a single GitHub issue in the Test Flakes project:
// a plain github.Issue plus our associated data.
type Issue struct {
	*github.Issue
	ScriptText string         // extracted watchflakes script
	Script     *script.Script // compiled script

	// initialized by readComments
	Stale    bool                   // issue comments may be stale
	Comments []*github.IssueComment // all issue comments
	NewBody  bool                   // issue body (containing script) is newer than last watchflakes comment
	Mentions map[string]bool        // log URLs that have already been posted in watchflakes comments

	// what to send back to the issue
	Error string         // error message (markdown) to post back to issue
	Post  []*FailurePost // failures to post back to issue
}

func (i *Issue) String() string { return fmt.Sprintf("#%d", i.Number) }

var (
	gh         *github.Client
	repo       *github.Repo
	labels     map[string]*github.Label
	testFlakes *github.Project
)

var scriptRE = regexp.MustCompile(`(?m)(^( {4}|\t)#!watchflakes\n((( {4}|\t).*)?\n)+|^\x60{3}\n#!watchflakes\n(([^\x60].*)?\n)+\x60{3}\n)`)

// readIssues reads the GitHub issues in the Test Flakes project.
// It also sets up the repo, labels, and testFlakes variables for
// use by other functions below.
func readIssues(old []*Issue) ([]*Issue, error) {
	// Find repo.
	r, err := gh.Repo("golang", "go")
	if err != nil {
		return nil, err
	}
	repo = r

	// Find labels.
	list, err := gh.SearchLabels("golang", "go", "")
	if err != nil {
		return nil, err
	}
	labels = make(map[string]*github.Label)
	for _, label := range list {
		labels[label.Name] = label
	}

	// Find Test Flakes project.
	ps, err := gh.Projects("golang", "")
	if err != nil {
		return nil, err
	}
	for _, p := range ps {
		if p.Title == "Test Flakes" {
			testFlakes = p
			break
		}
	}
	if testFlakes == nil {
		return nil, fmt.Errorf("cannot find Test Flakes project")
	}

	cache := make(map[int]*Issue)
	for _, issue := range old {
		cache[issue.Number] = issue
	}
	// Read all issues in Test Flakes.
	var issues []*Issue
	items, err := gh.ProjectItems(testFlakes)
	if err != nil {
		return nil, err
	}
	for _, item := range items {
		if item.Issue != nil {
			issue := &Issue{Issue: item.Issue, NewBody: true, Stale: true}
			if c := cache[item.Issue.Number]; c != nil {
				// Carry conservative NewBody, Mentions data forward
				// to avoid round trips about things we already know.
				if c.Issue.LastEditedAt.Equal(item.Issue.LastEditedAt) {
					issue.NewBody = c.NewBody
				}
				issue.Mentions = c.Mentions
			}
			issues = append(issues, issue)
		}
	}
	sort.Slice(issues, func(i, j int) bool {
		return issues[i].Number < issues[j].Number
	})

	return issues, nil
}

// findScripts finds the scripts in the issues,
// initializing issue.Script and .ScriptText or else .Error
// in each issue.
func findScripts(issues []*Issue) {
	for _, issue := range issues {
		findScript(issue)
	}
}

var noScriptError = `
Sorry, but I can't find a watchflakes script at the start of the issue description.
See https://go.dev/wiki/Watchflakes for details.
`

var parseScriptError = `
Sorry, but there were parse errors in the watch flakes script.
The script I found was:

%s

And the problems were:

%s

See https://go.dev/wiki/Watchflakes for details.
`

// findScript finds the script in issue and parses it.
// If the script is not found or has any parse errors,
// issue.Error is filled in.
// Otherwise issue.ScriptText and issue.Script are filled in.
func findScript(issue *Issue) {
	// Extract ```-fenced or indented code block at start of issue description (body).
	body := strings.ReplaceAll(issue.Body, "\r\n", "\n")
	lines := strings.SplitAfter(body, "\n")
	for len(lines) > 0 && strings.TrimSpace(lines[0]) == "" {
		lines = lines[1:]
	}
	text := ""
	if len(lines) > 0 && strings.HasPrefix(lines[0], "```") {
		marker := lines[0]
		n := 0
		for n < len(marker) && marker[n] == '`' {
			n++
		}
		marker = marker[:n]
		i := 1
		for i := 1; i < len(lines); i++ {
			if strings.HasPrefix(lines[i], marker) && strings.TrimSpace(strings.TrimLeft(lines[i], "`")) == "" {
				text = strings.Join(lines[1:i], "")
				break
			}
		}
		if i < len(lines) {
		}
	} else if strings.HasPrefix(lines[0], "\t") || strings.HasPrefix(lines[0], "    ") {
		i := 1
		for i < len(lines) && (strings.HasPrefix(lines[i], "\t") || strings.HasPrefix(lines[i], "    ")) {
			i++
		}
		text = strings.Join(lines[:i], "")
	}

	// Must start with #!watchflakes so we're sure it is for us.
	hdr, _, _ := strings.Cut(text, "\n")
	hdr = strings.TrimSpace(hdr)
	if hdr != "#!watchflakes" {
		issue.Error = noScriptError
		return
	}

	// Parse script.
	issue.ScriptText = text
	s, errs := script.Parse("script", text, fields)
	if len(errs) > 0 {
		var errtext strings.Builder
		for _, err := range errs {
			errtext.WriteString(err.Error())
			errtext.WriteString("\n")
		}
		issue.Error = fmt.Sprintf(parseScriptError, indent("\t", text), indent("\t", errtext.String()))
		return
	}

	issue.Script = s
}

func postIssueErrors(issues []*Issue) []error {
	var errors []error
	for _, issue := range issues {
		if issue.Error != "" && issue.NewBody {
			readComments(issue)
			if issue.NewBody {
				fmt.Printf(" - #%d script error\n", issue.Number)
				if *verbose {
					fmt.Printf("\n%s\n", indent(spaces[:7], issue.Error))
				}
				if *post {
					if err := postComment(issue, issue.Error); err != nil {
						errors = append(errors, err)
						continue
					}
					issue.NewBody = false
				}
			}
		}
	}
	return errors
}

// updateText returns the text for the GitHub update on issue.
func updateText(issue *Issue) string {
	if len(issue.Post) == 0 {
		return ""
	}

	var b strings.Builder
	fmt.Fprintf(&b, "Found new dashboard test flakes for:\n\n%s", indent(spaces[:4], issue.ScriptText))
	for _, f := range issue.Post {
		b.WriteString("\n")
		_ = f
		b.WriteString(f.Markdown())
	}
	return b.String()
}

// reportNew creates and returns a new issue for reporting the failure.
// If *post is false, reportNew returns a fake issue with number 0.
func reportNew(fp *FailurePost) (*Issue, error) {
	var pattern, title string
	if fp.Pkg != "" {
		pattern = fmt.Sprintf("pkg == %q && test == %q", fp.Pkg, fp.Test)
		test := fp.Test
		if test == "" {
			test = "unrecognized"
		}
		title = shortPkg(fp.Pkg) + ": " + test + " failures"
	} else if fp.Test != "" {
		pattern = fmt.Sprintf("repo == %q && pkg == %q && test == %q", fp.Repo, "", fp.Test)
		title = "build: " + fp.Test + " failures"
	} else if fp.IsBuildFailure() {
		pattern = fmt.Sprintf("builder == %q && repo == %q && mode == %q", fp.Builder, fp.Repo, "build")
		title = "build: build failure on " + fp.Builder
	} else {
		pattern = fmt.Sprintf("builder == %q && repo == %q && pkg == %q && test == %q", fp.Builder, fp.Repo, "", "")
		title = "build: unrecognized failures on " + fp.Builder
	}

	var msg strings.Builder
	fmt.Fprintf(&msg, "```\n#!watchflakes\ndefault <- %s\n```\n\n", pattern)
	fmt.Fprintf(&msg, "Issue created automatically to collect these failures.\n\n")
	fmt.Fprintf(&msg, "Example ([log](%s)):\n\n%s", fp.URL, indent(spaces[:4], fp.Snippet))

	// TODO: for a single test failure, add a link to LUCI history page.

	fmt.Printf("# new issue: %s\n%s\n%s\n%s\n\n%s\n", title, fp.String(), fp.URL, pattern, fp.Snippet)
	if *verbose {
		fmt.Printf("\n%s\n", indent(spaces[:3], msg.String()))
	}

	issue := new(Issue)
	if *post {
		issue.Issue = newIssue(title, msg.String())
	} else {
		issue.Issue = &github.Issue{Title: title, Body: msg.String()}
	}
	findScript(issue)
	if issue.Error != "" {
		return nil, fmt.Errorf("cannot find script in generated issue:\nBody:\n%s\n\nError:\n%s", issue.Body, issue.Error)
	}
	issue.Post = append(issue.Post, fp)
	return issue, nil
}

// signature is the signature we add to the end of every comment or issue body
// we post on GitHub. It links to documentation for users, and it also serves as
// a way to identify the comments that we posted, since watchflakes can be run
// as gopherbot or as an ordinary user.
const signature = "\n\n— [watchflakes](https://go.dev/wiki/Watchflakes)\n"

// keep in sync with buildURL function in luci.go
// An older version reported ci.chromium.org/ui/b instead of ci.chromium.org/b,
// match them as well.
var buildUrlRE = regexp.MustCompile(`[("']https://ci.chromium.org/(ui/)?b/[0-9]+['")]`)

// readComments loads the comments for the given issue,
// setting the Comments, NewBody, and Mentions fields.
func readComments(issue *Issue) {
	if issue.Number == 0 || !issue.Stale {
		return
	}
	log.Printf("readComments %d", issue.Number)
	comments, err := gh.IssueComments(issue.Issue)
	if err != nil {
		log.Fatal(err)
	}
	issue.Comments = comments
	mtime := issue.LastEditedAt
	if mtime.IsZero() {
		mtime = issue.CreatedAt
	}
	issue.Mentions = make(map[string]bool)
	issue.NewBody = true // until proven otherwise
	for _, com := range comments {
		// Only consider comments we signed.
		if !strings.Contains(com.Body, "\n— watchflakes") && !strings.Contains(com.Body, "\n— [watchflakes](") {
			continue
		}
		if com.CreatedAt.After(issue.LastEditedAt) {
			issue.NewBody = false
		}
		for _, link := range buildUrlRE.FindAllString(com.Body, -1) {
			l := strings.Trim(link, "()\"'")
			issue.Mentions[l] = true
			// An older version reported ci.chromium.org/ui/b instead of ci.chromium.org/b,
			// match them as well.
			issue.Mentions[strings.Replace(l, "ci.chromium.org/ui/b/", "ci.chromium.org/b/", 1)] = true
		}
	}
	issue.Stale = false
}

// newIssue creates a new issue with the given title and body,
// setting the NeedsInvestigation label and placing the issue int
// the Test Flakes project.
// It automatically adds signature to the body.
func newIssue(title, body string) *github.Issue {
	var args []any
	if lab := labels["NeedsInvestigation"]; lab != nil {
		args = append(args, lab)
	}
	args = append(args, testFlakes)

	issue, err := gh.CreateIssue(repo, title, body+signature, args...)
	if err != nil {
		log.Fatal(err)
	}
	return issue
}

// postComment posts a new comment on the issue.
// It automatically adds signature to the comment.
func postComment(issue *Issue, body string) error {
	if len(body) > 50000 {
		// Apparently GitHub GraphQL API limits comment length to 65536.
		body = body[:50000] + "\n</details>\n(... long comment truncated ...)\n"
	}
	if issue.Issue.Closed {
		reopen := false
		for _, p := range issue.Post {
			_ = p
			if p.Time.After(issue.ClosedAt) {
				reopen = true
				break
			}
		}
		if reopen {
			if err := gh.ReopenIssue(issue.Issue); err != nil {
				return err
			}
		}
	}
	return gh.AddIssueComment(issue.Issue, body+signature)
}
