// 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"
	"net/http"
	"regexp"
	"runtime"
	"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)
}

// defaultTransportWithRSCIOGitHubAuth is an http.RoundTripper
// that implements authentication for the rsc.io/github.Client
// type, but otherwise defers to http.DefaultTransport.
//
// It's brittle and exists only until there's a better API for
// providing an *http.Client to the rsc.io/github package.
type defaultTransportWithRSCIOGitHubAuth struct {
	GitHubToken interface{ SetAuthHeader(*http.Request) }
}

func (t defaultTransportWithRSCIOGitHubAuth) RoundTrip(req *http.Request) (*http.Response, error) {
	if req.URL.Host == "api.github.com" && req.URL.Scheme == "https" {
		if req.Host != "api.github.com" {
			return nil, fmt.Errorf("internal error: req.Host is %q, want api.github.com", req.Host)
		}
		// Confirm that the caller is the expected method of rsc.io/github.Client.
		//
		// Note: This is brittle and not great. But it works for now, and will go
		// away after we can pass a custom *http.Client to github.Client directly.
		var pc = make([]uintptr, 1)
		if n := runtime.Callers(6, pc); n == 0 {
			return nil, fmt.Errorf("internal error: unknown caller")
		} else if f, _ := runtime.CallersFrames(pc).Next(); f.Function != "rsc.io/github.(*Client).graphQL" {
			return nil, fmt.Errorf("internal error: caller is %q, want rsc.io/github", f.Function)
		}
		req = req.Clone(req.Context())
		t.GitHubToken.SetAuthHeader(req)
	}
	return http.DefaultTransport.RoundTrip(req)
}
