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

// The gopherbot command runs Go's gopherbot role account on
// GitHub and Gerrit.
//
// General documentation is at https://go.dev/wiki/gopherbot.
// Consult the tasks slice in gopherbot.go for an up-to-date
// list of all gopherbot tasks.
package main

import (
	"bufio"
	"bytes"
	"context"
	"crypto/tls"
	"encoding/json"
	"errors"
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"sync"
	"time"
	"unicode"

	"cloud.google.com/go/compute/metadata"
	"github.com/google/go-github/v48/github"
	"github.com/shurcooL/githubv4"
	"go4.org/strutil"
	"golang.org/x/build/devapp/owners"
	"golang.org/x/build/gerrit"
	"golang.org/x/build/internal/foreach"
	"golang.org/x/build/internal/gophers"
	"golang.org/x/build/internal/secret"
	"golang.org/x/build/maintner"
	"golang.org/x/build/maintner/godata"
	"golang.org/x/build/maintner/maintnerd/apipb"
	"golang.org/x/exp/slices"
	"golang.org/x/oauth2"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
)

var (
	dryRun          = flag.Bool("dry-run", false, "just report what would've been done, without changing anything")
	daemon          = flag.Bool("daemon", false, "run in daemon mode")
	githubTokenFile = flag.String("github-token-file", filepath.Join(os.Getenv("HOME"), "keys", "github-gobot"), `File to load GitHub token from. File should be of form <username>:<token>`)
	// go here: https://go-review.googlesource.com/settings#HTTPCredentials
	// click "Obtain Password"
	// The next page will have a .gitcookies file - look for the part that has
	// "git-youremail@yourcompany.com=password". Copy and paste that to the
	// token file with a colon in between the email and password.
	gerritTokenFile = flag.String("gerrit-token-file", filepath.Join(os.Getenv("HOME"), "keys", "gerrit-gobot"), `File to load Gerrit token from. File should be of form <git-email>:<token>`)

	onlyRun = flag.String("only-run", "", "if non-empty, the name of a task to run. Mostly for debugging, but tasks (like 'kicktrain') may choose to only run in explicit mode")
)

func init() {
	flag.Usage = func() {
		output := flag.CommandLine.Output()
		fmt.Fprintf(output, "gopherbot runs Go's gopherbot role account on GitHub and Gerrit.\n\n")
		flag.PrintDefaults()
		fmt.Fprintln(output, "")
		fmt.Fprintln(output, "Tasks (can be used for the --only-run flag):")
		for _, t := range tasks {
			fmt.Fprintf(output, "  %q\n", t.name)
		}
	}
}

const (
	gopherbotGitHubID = 8566911
)

const (
	gobotGerritID     = "5976"
	gerritbotGerritID = "12446"
	kokoroGerritID    = "37747"
	goLUCIGerritID    = "60063"
	triciumGerritID   = "62045"
)

// GitHub Label IDs for the golang/go repo.
const (
	needsDecisionID      = 373401956
	needsFixID           = 373399998
	needsInvestigationID = 373402289
	earlyInCycleID       = 626114143
)

// Label names (that are used in multiple places).
const (
	frozenDueToAge = "FrozenDueToAge"
)

// GitHub Milestone numbers for the golang/go repo.
var (
	proposal      = milestone{30, "Proposal"}
	unreleased    = milestone{22, "Unreleased"}
	unplanned     = milestone{6, "Unplanned"}
	gccgo         = milestone{23, "Gccgo"}
	vgo           = milestone{71, "vgo"}
	vulnUnplanned = milestone{288, "vuln/unplanned"}
)

// GitHub Milestone numbers for the golang/vscode-go repo.
var vscodeUntriaged = milestone{26, "Untriaged"}

type milestone struct {
	Number int
	Name   string
}

func getGitHubToken(ctx context.Context, sc *secret.Client) (string, error) {
	if metadata.OnGCE() && sc != nil {
		ctxSc, cancel := context.WithTimeout(ctx, 10*time.Second)
		defer cancel()

		token, err := sc.Retrieve(ctxSc, secret.NameMaintnerGitHubToken)
		if err == nil && token != "" {
			return token, nil
		}
	}
	slurp, err := os.ReadFile(*githubTokenFile)
	if err != nil {
		return "", err
	}
	f := strings.SplitN(strings.TrimSpace(string(slurp)), ":", 2)
	if len(f) != 2 || f[0] == "" || f[1] == "" {
		return "", fmt.Errorf("expected token %q to be of form <username>:<token>", slurp)
	}
	return f[1], nil
}

func getGerritAuth(ctx context.Context, sc *secret.Client) (username string, password string, err error) {
	if metadata.OnGCE() && sc != nil {
		ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
		defer cancel()

		token, err := sc.Retrieve(ctx, secret.NameGobotPassword)
		if err != nil {
			return "", "", err
		}
		return "git-gobot.golang.org", token, nil
	}

	var slurpBytes []byte
	slurpBytes, err = os.ReadFile(*gerritTokenFile)
	if err != nil {
		return "", "", err
	}
	slurp := string(slurpBytes)

	f := strings.SplitN(strings.TrimSpace(slurp), ":", 2)
	if len(f) == 1 {
		// assume the whole thing is the token
		return "git-gobot.golang.org", f[0], nil
	}
	if len(f) != 2 || f[0] == "" || f[1] == "" {
		return "", "", fmt.Errorf("expected Gerrit token %q to be of form <git-email>:<token>", slurp)
	}
	return f[0], f[1], nil
}

func getGitHubClients(ctx context.Context, sc *secret.Client) (*github.Client, *githubv4.Client, error) {
	token, err := getGitHubToken(ctx, sc)
	if err != nil {
		if *dryRun {
			// Note: GitHub API v4 requires requests to be authenticated, which isn't implemented here.
			return github.NewClient(http.DefaultClient), githubv4.NewClient(http.DefaultClient), nil
		}
		return nil, nil, err
	}
	ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: token})
	tc := oauth2.NewClient(context.Background(), ts)
	return github.NewClient(tc), githubv4.NewClient(tc), nil
}

func getGerritClient(ctx context.Context, sc *secret.Client) (*gerrit.Client, error) {
	username, token, err := getGerritAuth(ctx, sc)
	if err != nil {
		if *dryRun {
			c := gerrit.NewClient("https://go-review.googlesource.com", gerrit.NoAuth)
			return c, nil
		}
		return nil, err
	}
	c := gerrit.NewClient("https://go-review.googlesource.com", gerrit.BasicAuth(username, token))
	return c, nil
}

func getMaintnerClient(ctx context.Context) (apipb.MaintnerServiceClient, error) {
	ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
	defer cancel()
	mServer := "maintner.golang.org:443"
	cc, err := grpc.DialContext(ctx, mServer,
		grpc.WithBlock(),
		grpc.WithTransportCredentials(credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})))
	if err != nil {
		return nil, err
	}
	return apipb.NewMaintnerServiceClient(cc), nil
}

type gerritChange struct {
	project string
	num     int32
}

func (c gerritChange) ID() string {
	// https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
	return fmt.Sprintf("%s~%d", c.project, c.num)
}

func (c gerritChange) String() string {
	return c.ID()
}

type githubIssue struct {
	repo maintner.GitHubRepoID
	num  int32
}

func main() {
	flag.Parse()

	var sc *secret.Client
	if metadata.OnGCE() {
		sc = secret.MustNewClient()
	}
	ctx := context.Background()

	ghV3, ghV4, err := getGitHubClients(ctx, sc)
	if err != nil {
		log.Fatal(err)
	}
	gerrit, err := getGerritClient(ctx, sc)
	if err != nil {
		log.Fatal(err)
	}
	mc, err := getMaintnerClient(ctx)
	if err != nil {
		log.Fatal(err)
	}

	var goRepo = maintner.GitHubRepoID{Owner: "golang", Repo: "go"}
	var vscode = maintner.GitHubRepoID{Owner: "golang", Repo: "vscode-go"}
	bot := &gopherbot{
		ghc:    ghV3,
		ghV4:   ghV4,
		gerrit: gerrit,
		mc:     mc,
		is:     ghV3.Issues,
		deletedChanges: map[gerritChange]bool{
			{"crypto", 35958}:  true,
			{"scratch", 71730}: true,
			{"scratch", 71850}: true,
			{"scratch", 72090}: true,
			{"scratch", 72091}: true,
			{"scratch", 72110}: true,
			{"scratch", 72131}: true,
		},
		deletedIssues: map[githubIssue]bool{
			{goRepo, 13084}: true,
			{goRepo, 23772}: true,
			{goRepo, 27223}: true,
			{goRepo, 28522}: true,
			{goRepo, 29309}: true,
			{goRepo, 32047}: true,
			{goRepo, 32048}: true,
			{goRepo, 32469}: true,
			{goRepo, 32706}: true,
			{goRepo, 32737}: true,
			{goRepo, 33315}: true,
			{goRepo, 33316}: true,
			{goRepo, 33592}: true,
			{goRepo, 33593}: true,
			{goRepo, 33697}: true,
			{goRepo, 33785}: true,
			{goRepo, 34296}: true,
			{goRepo, 34476}: true,
			{goRepo, 34766}: true,
			{goRepo, 34780}: true,
			{goRepo, 34786}: true,
			{goRepo, 34821}: true,
			{goRepo, 35493}: true,
			{goRepo, 35649}: true,
			{goRepo, 36322}: true,
			{goRepo, 36323}: true,
			{goRepo, 36324}: true,
			{goRepo, 36342}: true,
			{goRepo, 36343}: true,
			{goRepo, 36406}: true,
			{goRepo, 36517}: true,
			{goRepo, 36829}: true,
			{goRepo, 36885}: true,
			{goRepo, 36933}: true,
			{goRepo, 36939}: true,
			{goRepo, 36941}: true,
			{goRepo, 36947}: true,
			{goRepo, 36962}: true,
			{goRepo, 36963}: true,
			{goRepo, 37516}: true,
			{goRepo, 37522}: true,
			{goRepo, 37582}: true,
			{goRepo, 37896}: true,
			{goRepo, 38132}: true,
			{goRepo, 38241}: true,
			{goRepo, 38483}: true,
			{goRepo, 38560}: true,
			{goRepo, 38840}: true,
			{goRepo, 39112}: true,
			{goRepo, 39141}: true,
			{goRepo, 39229}: true,
			{goRepo, 39234}: true,
			{goRepo, 39335}: true,
			{goRepo, 39401}: true,
			{goRepo, 39453}: true,
			{goRepo, 39522}: true,
			{goRepo, 39718}: true,
			{goRepo, 40400}: true,
			{goRepo, 40593}: true,
			{goRepo, 40600}: true,
			{goRepo, 41211}: true,
			{goRepo, 41336}: true,
			{goRepo, 41649}: true,
			{goRepo, 41650}: true,
			{goRepo, 41655}: true,
			{goRepo, 41675}: true,
			{goRepo, 41676}: true,
			{goRepo, 41678}: true,
			{goRepo, 41679}: true,
			{goRepo, 41714}: true,
			{goRepo, 42309}: true,
			{goRepo, 43102}: true,
			{goRepo, 43169}: true,
			{goRepo, 43231}: true,
			{goRepo, 43330}: true,
			{goRepo, 43409}: true,
			{goRepo, 43410}: true,
			{goRepo, 43411}: true,
			{goRepo, 43433}: true,
			{goRepo, 43613}: true,
			{goRepo, 43751}: true,
			{goRepo, 44124}: true,
			{goRepo, 44185}: true,
			{goRepo, 44566}: true,
			{goRepo, 44652}: true,
			{goRepo, 44711}: true,
			{goRepo, 44768}: true,
			{goRepo, 44769}: true,
			{goRepo, 44771}: true,
			{goRepo, 44773}: true,
			{goRepo, 44871}: true,
			{goRepo, 45018}: true,
			{goRepo, 45082}: true,
			{goRepo, 45201}: true,
			{goRepo, 45202}: true,
			{goRepo, 47140}: true,

			{vscode, 298}:  true,
			{vscode, 524}:  true,
			{vscode, 650}:  true,
			{vscode, 741}:  true,
			{vscode, 773}:  true,
			{vscode, 959}:  true,
			{vscode, 1402}: true,
		},
	}
	for n := int32(55359); n <= 55828; n++ {
		bot.deletedIssues[githubIssue{goRepo, n}] = true
	}
	bot.initCorpus()

	for {
		t0 := time.Now()
		taskErrors := bot.doTasks(ctx)
		for _, err := range taskErrors {
			log.Print(err)
		}
		botDur := time.Since(t0)
		log.Printf("gopherbot ran in %v", botDur)
		if !*daemon {
			if len(taskErrors) > 0 {
				os.Exit(1)
			}
			return
		}
		if len(taskErrors) > 0 {
			log.Printf("sleeping 30s after previous error.")
			time.Sleep(30 * time.Second)
		}
		for {
			t0 := time.Now()
			err := bot.corpus.Update(ctx)
			if err != nil {
				if err == maintner.ErrSplit {
					log.Print("Corpus out of sync. Re-fetching corpus.")
					bot.initCorpus()
				} else {
					log.Printf("corpus.Update: %v; sleeping 15s", err)
					time.Sleep(15 * time.Second)
					continue
				}
			}
			log.Printf("got corpus update after %v", time.Since(t0))
			break
		}
		lastTask = ""
	}
}

type gopherbot struct {
	ghc    *github.Client
	ghV4   *githubv4.Client
	gerrit *gerrit.Client
	mc     apipb.MaintnerServiceClient
	corpus *maintner.Corpus
	gorepo *maintner.GitHubRepo
	is     issuesService

	knownContributors map[string]bool

	// Until golang.org/issue/22635 is fixed, keep a map of changes and issues
	// that were deleted to prevent calls to Gerrit or GitHub that will always 404.
	deletedChanges map[gerritChange]bool
	deletedIssues  map[githubIssue]bool

	releases struct {
		sync.Mutex
		lastUpdate time.Time
		major      []string          // Last two releases and the next upcoming release, like: "1.9", "1.10", "1.11".
		nextMinor  map[string]string // Key is a major release like "1.9", value is its next minor release like "1.9.7".
	}
}

var tasks = []struct {
	name string
	fn   func(*gopherbot, context.Context) error
}{
	// Tasks that are specific to the golang/go repo.
	{"kicktrain", (*gopherbot).getOffKickTrain},
	{"label build issues", (*gopherbot).labelBuildIssues},
	{"label compiler/runtime issues", (*gopherbot).labelCompilerRuntimeIssues},
	{"label mobile issues", (*gopherbot).labelMobileIssues},
	{"label tools issues", (*gopherbot).labelToolsIssues},
	{"label website issues", (*gopherbot).labelWebsiteIssues},
	{"label pkgsite issues", (*gopherbot).labelPkgsiteIssues},
	{"label proxy.golang.org issues", (*gopherbot).labelProxyIssues},
	{"label vulncheck or vulndb issues", (*gopherbot).labelVulnIssues},
	{"label proposals", (*gopherbot).labelProposals},
	{"handle gopls issues", (*gopherbot).handleGoplsIssues},
	{"handle telemetry issues", (*gopherbot).handleTelemetryIssues},
	{"open cherry pick issues", (*gopherbot).openCherryPickIssues},
	{"close cherry pick issues", (*gopherbot).closeCherryPickIssues},
	{"set subrepo milestones", (*gopherbot).setSubrepoMilestones},
	{"set misc milestones", (*gopherbot).setMiscMilestones},
	{"apply minor release milestones", (*gopherbot).setMinorMilestones},
	{"update needs", (*gopherbot).updateNeeds},

	// Tasks that can be applied to many repos.
	{"freeze old issues", (*gopherbot).freezeOldIssues},
	{"label documentation issues", (*gopherbot).labelDocumentationIssues},
	{"close stale WaitingForInfo", (*gopherbot).closeStaleWaitingForInfo},
	{"apply labels from comments", (*gopherbot).applyLabelsFromComments},

	// Gerrit tasks are applied to all projects by default.
	{"abandon scratch reviews", (*gopherbot).abandonScratchReviews},
	{"assign reviewers to CLs", (*gopherbot).assignReviewersToCLs},
	{"auto-submit CLs", (*gopherbot).autoSubmitCLs},

	// Tasks that are specific to the golang/vscode-go repo.
	{"set vscode-go milestones", (*gopherbot).setVSCodeGoMilestones},

	{"access", (*gopherbot).whoNeedsAccess},
	{"cl2issue", (*gopherbot).cl2issue},
	{"congratulate new contributors", (*gopherbot).congratulateNewContributors},
	{"un-wait CLs", (*gopherbot).unwaitCLs},
}

// gardenIssues reports whether GopherBot should perform general issue
// gardening tasks for the repo.
func gardenIssues(repo *maintner.GitHubRepo) bool {
	if repo.ID().Owner != "golang" {
		return false
	}
	switch repo.ID().Repo {
	case "go", "vscode-go", "vulndb":
		return true
	}
	return false
}

func (b *gopherbot) initCorpus() {
	ctx := context.Background()
	corpus, err := godata.Get(ctx)
	if err != nil {
		log.Fatalf("godata.Get: %v", err)
	}

	repo := corpus.GitHub().Repo("golang", "go")
	if repo == nil {
		log.Fatal("Failed to find Go repo in Corpus.")
	}

	b.corpus = corpus
	b.gorepo = repo
}

// doTasks performs tasks in sequence. It doesn't stop if
// if encounters an error, but reports errors at the end.
func (b *gopherbot) doTasks(ctx context.Context) []error {
	var errs []error
	for _, task := range tasks {
		if *onlyRun != "" && task.name != *onlyRun {
			continue
		}
		err := task.fn(b, ctx)
		if err != nil {
			errs = append(errs, fmt.Errorf("%s: %v", task.name, err))
		}
	}
	return errs
}

// issuesService represents portions of github.IssuesService that we want to override in tests.
type issuesService interface {
	ListLabelsByIssue(ctx context.Context, owner string, repo string, number int, opt *github.ListOptions) ([]*github.Label, *github.Response, error)
	AddLabelsToIssue(ctx context.Context, owner string, repo string, number int, labels []string) ([]*github.Label, *github.Response, error)
	RemoveLabelForIssue(ctx context.Context, owner string, repo string, number int, label string) (*github.Response, error)
}

func (b *gopherbot) addLabel(ctx context.Context, repoID maintner.GitHubRepoID, gi *maintner.GitHubIssue, label string) error {
	return b.addLabels(ctx, repoID, gi, []string{label})
}

func (b *gopherbot) addLabels(ctx context.Context, repoID maintner.GitHubRepoID, gi *maintner.GitHubIssue, labels []string) error {
	var toAdd []string
	for _, label := range labels {
		if gi.HasLabel(label) {
			log.Printf("Issue %d already has label %q; no need to send request to add it", gi.Number, label)
			continue
		}
		printIssue("label-"+label, repoID, gi)
		toAdd = append(toAdd, label)
	}

	if *dryRun || len(toAdd) == 0 {
		return nil
	}

	_, resp, err := b.is.AddLabelsToIssue(ctx, repoID.Owner, repoID.Repo, int(gi.Number), toAdd)
	if err != nil && resp != nil && (resp.StatusCode == http.StatusNotFound || resp.StatusCode == http.StatusGone) {
		// TODO(golang/go#40640) - This issue was transferred or otherwise is gone. We should permanently skip it. This
		// is a temporary fix to keep gopherbot working.
		log.Printf("addLabels: Issue %v#%v returned %s when trying to add labels. Skipping. See golang/go#40640.", repoID, gi.Number, resp.Status)
		b.deletedIssues[githubIssue{repoID, gi.Number}] = true
		return nil
	}
	return err
}

// removeLabel removes the label from the given issue in the given repo.
func (b *gopherbot) removeLabel(ctx context.Context, repoID maintner.GitHubRepoID, gi *maintner.GitHubIssue, label string) error {
	return b.removeLabels(ctx, repoID, gi, []string{label})
}

func (b *gopherbot) removeLabels(ctx context.Context, repoID maintner.GitHubRepoID, gi *maintner.GitHubIssue, labels []string) error {
	var removeLabels bool
	for _, l := range labels {
		if !gi.HasLabel(l) {
			log.Printf("Issue %d (in maintner) does not have label %q; no need to send request to remove it", gi.Number, l)
			continue
		}
		printIssue("label-"+l, repoID, gi)
		removeLabels = true
	}

	if *dryRun || !removeLabels {
		return nil
	}

	ghLabels, err := labelsForIssue(ctx, repoID, b.is, int(gi.Number))
	if err != nil {
		return err
	}
	toRemove := make(map[string]bool)
	for _, l := range labels {
		toRemove[l] = true
	}

	for _, l := range ghLabels {
		if toRemove[l] {
			if err := removeLabelFromIssue(ctx, repoID, b.is, int(gi.Number), l); err != nil {
				log.Printf("Could not remove label %q from issue %d: %v", l, gi.Number, err)
				continue
			}
		}
	}
	return nil
}

// labelsForIssue returns all labels for the given issue in the given repo.
func labelsForIssue(ctx context.Context, repoID maintner.GitHubRepoID, issues issuesService, issueNum int) ([]string, error) {
	ghLabels, _, err := issues.ListLabelsByIssue(ctx, repoID.Owner, repoID.Repo, issueNum, &github.ListOptions{PerPage: 100})
	if err != nil {
		return nil, fmt.Errorf("could not list labels for %s#%d: %v", repoID, issueNum, err)
	}
	var labels []string
	for _, l := range ghLabels {
		labels = append(labels, l.GetName())
	}
	return labels, nil
}

// removeLabelFromIssue removes the given label from the given repo with the
// given issueNum. If the issue did not have the label already (or the label
// didn't exist), return nil.
func removeLabelFromIssue(ctx context.Context, repoID maintner.GitHubRepoID, issues issuesService, issueNum int, label string) error {
	_, err := issues.RemoveLabelForIssue(ctx, repoID.Owner, repoID.Repo, issueNum, label)
	if ge, ok := err.(*github.ErrorResponse); ok && ge.Response != nil && ge.Response.StatusCode == http.StatusNotFound {
		return nil
	}
	return err
}

func (b *gopherbot) setMilestone(ctx context.Context, repoID maintner.GitHubRepoID, gi *maintner.GitHubIssue, m milestone) error {
	printIssue("milestone-"+m.Name, repoID, gi)
	if *dryRun {
		return nil
	}
	_, _, err := b.ghc.Issues.Edit(ctx, repoID.Owner, repoID.Repo, int(gi.Number), &github.IssueRequest{
		Milestone: github.Int(m.Number),
	})
	return err
}

func (b *gopherbot) addGitHubComment(ctx context.Context, repo *maintner.GitHubRepo, issueNum int32, msg string) error {
	var since time.Time
	if gi := repo.Issue(issueNum); gi != nil {
		dup := false
		gi.ForeachComment(func(c *maintner.GitHubComment) error {
			since = c.Updated
			// TODO: check for gopherbot as author? check for exact match?
			// This seems fine for now.
			if strings.Contains(c.Body, msg) {
				dup = true
				return errStopIteration
			}
			return nil
		})
		if dup {
			// Comment's already been posted. Nothing to do.
			return nil
		}
	}
	// See if there is a dup comment from when gopherbot last got
	// its data from maintner.
	opt := &github.IssueListCommentsOptions{ListOptions: github.ListOptions{PerPage: 1000}}
	if !since.IsZero() {
		opt.Since = &since
	}
	ics, resp, err := b.ghc.Issues.ListComments(ctx, repo.ID().Owner, repo.ID().Repo, int(issueNum), opt)
	if err != nil {
		// TODO(golang/go#40640) - This issue was transferred or otherwise is gone. We should permanently skip it. This
		// is a temporary fix to keep gopherbot working.
		if resp != nil && resp.StatusCode == http.StatusNotFound {
			log.Printf("addGitHubComment: Issue %v#%v returned a 404 when trying to load comments. Skipping. See golang/go#40640.", repo.ID(), issueNum)
			b.deletedIssues[githubIssue{repo.ID(), issueNum}] = true
			return nil
		}
		return err
	}
	for _, ic := range ics {
		if strings.Contains(ic.GetBody(), msg) {
			// Dup.
			return nil
		}
	}
	if *dryRun {
		log.Printf("[dry-run] would add comment to github.com/%s/issues/%d: %v", repo.ID(), issueNum, msg)
		return nil
	}
	_, resp, createError := b.ghc.Issues.CreateComment(ctx, repo.ID().Owner, repo.ID().Repo, int(issueNum), &github.IssueComment{
		Body: github.String(msg),
	})
	if createError != nil && resp != nil && resp.StatusCode == http.StatusUnprocessableEntity {
		// While maintner's tracking of deleted issues is incomplete (see go.dev/issue/30184),
		// we sometimes see a deleted issue whose /comments endpoint returns 200 OK with an
		// empty list, so the error check from ListComments doesn't catch it. (The deleted
		// issue 55403 is an example of such a case.) So check again with the Get endpoint,
		// which seems to return 404 more reliably in such cases at least as of 2022-10-11.
		if _, resp, err := b.ghc.Issues.Get(ctx, repo.ID().Owner, repo.ID().Repo, int(issueNum)); err != nil &&
			resp != nil && resp.StatusCode == http.StatusNotFound {
			log.Printf("addGitHubComment: Issue %v#%v returned a 404 after posting comment failed with 422. Skipping. See go.dev/issue/30184.", repo.ID(), issueNum)
			b.deletedIssues[githubIssue{repo.ID(), issueNum}] = true
			return nil
		}
	}
	return createError
}

// createGitHubIssue returns the number of the created issue, or 4242 in dry-run mode.
// baseEvent is the timestamp of the event causing this action, and is used for de-duplication.
func (b *gopherbot) createGitHubIssue(ctx context.Context, title, msg string, labels []string, baseEvent time.Time) (int, error) {
	var dup int
	b.gorepo.ForeachIssue(func(gi *maintner.GitHubIssue) error {
		// TODO: check for gopherbot as author? check for exact match?
		// This seems fine for now.
		if gi.Title == title {
			dup = int(gi.Number)
			return errStopIteration
		}
		return nil
	})
	if dup != 0 {
		// Issue's already been posted. Nothing to do.
		return dup, nil
	}
	// See if there is a dup issue from when gopherbot last got its data from maintner.
	is, _, err := b.ghc.Issues.ListByRepo(ctx, "golang", "go", &github.IssueListByRepoOptions{
		State:       "all",
		ListOptions: github.ListOptions{PerPage: 100},
		Since:       baseEvent,
	})
	if err != nil {
		return 0, err
	}
	for _, i := range is {
		if i.GetTitle() == title {
			// Dup.
			return i.GetNumber(), nil
		}
	}
	if *dryRun {
		log.Printf("[dry-run] would create issue with title %s and labels %v\n%s", title, labels, msg)
		return 4242, nil
	}
	i, _, err := b.ghc.Issues.Create(ctx, "golang", "go", &github.IssueRequest{
		Title:  github.String(title),
		Body:   github.String(msg),
		Labels: &labels,
	})
	return i.GetNumber(), err
}

// issueCloseReason is a reason given when closing an issue on GitHub.
// See https://docs.github.com/en/issues/tracking-your-work-with-issues/closing-an-issue.
type issueCloseReason *string

var (
	completed  issueCloseReason = github.String("completed")   // Done, closed, fixed, resolved.
	notPlanned issueCloseReason = github.String("not_planned") // Won't fix, can't repro, duplicate, stale.
)

// closeGitHubIssue closes a GitHub issue.
// reason specifies why it's being closed. (GitHub's default reason on 2023-06-12 is "completed".)
func (b *gopherbot) closeGitHubIssue(ctx context.Context, repoID maintner.GitHubRepoID, number int32, reason issueCloseReason) error {
	if *dryRun {
		var suffix string
		if reason != nil {
			suffix = " as " + *reason
		}
		log.Printf("[dry-run] would close go.dev/issue/%v%s", number, suffix)
		return nil
	}
	_, _, err := b.ghc.Issues.Edit(ctx, repoID.Owner, repoID.Repo, int(number), &github.IssueRequest{
		State:       github.String("closed"),
		StateReason: reason,
	})
	return err
}

type gerritCommentOpts struct {
	OldPhrases []string
	Version    string // if empty, latest version is used
}

var emptyGerritCommentOpts gerritCommentOpts

// addGerritComment adds the given comment to the CL specified by the changeID
// and the patch set identified by the version.
//
// As an idempotence check, before adding the comment and the list
// of oldPhrases are checked against the CL to ensure that no phrase in the list
// has already been added to the list as a comment.
func (b *gopherbot) addGerritComment(ctx context.Context, changeID, comment string, opts *gerritCommentOpts) error {
	if b == nil {
		panic("nil gopherbot")
	}
	if *dryRun {
		log.Printf("[dry-run] would add comment to golang.org/cl/%s: %v", changeID, comment)
		return nil
	}
	if opts == nil {
		opts = &emptyGerritCommentOpts
	}
	// One final staleness check before sending a message: get the list
	// of comments from the API and check whether any of them match.
	info, err := b.gerrit.GetChange(ctx, changeID, gerrit.QueryChangesOpt{
		Fields: []string{"MESSAGES", "CURRENT_REVISION"},
	})
	if err != nil {
		return err
	}
	for _, msg := range info.Messages {
		if strings.Contains(msg.Message, comment) {
			return nil // Our comment is already there
		}
		for j := range opts.OldPhrases {
			// Message looks something like "Patch set X:\n\n(our text)"
			if strings.Contains(msg.Message, opts.OldPhrases[j]) {
				return nil // Our comment is already there
			}
		}
	}
	var rev string
	if opts.Version != "" {
		rev = opts.Version
	} else {
		rev = info.CurrentRevision
	}
	return b.gerrit.SetReview(ctx, changeID, rev, gerrit.ReviewInput{
		Message: comment,
	})
}

// Move any issue to "Unplanned" if it looks like it keeps getting kicked along between releases.
func (b *gopherbot) getOffKickTrain(ctx context.Context) error {
	// We only run this task if it was explicitly requested via
	// the --only-run flag.
	if *onlyRun == "" {
		return nil
	}
	type match struct {
		url   string
		title string
		gi    *maintner.GitHubIssue
	}
	var matches []match
	b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		curMilestone := gi.Milestone.Title
		if !strings.HasPrefix(curMilestone, "Go1.") || strings.Count(curMilestone, ".") != 1 {
			return nil
		}
		if gi.HasLabel("release-blocker") || gi.HasLabel("Security") {
			return nil
		}
		if len(gi.Assignees) > 0 {
			return nil
		}
		was := map[string]bool{}
		gi.ForeachEvent(func(e *maintner.GitHubIssueEvent) error {
			if e.Type == "milestoned" {
				switch e.Milestone {
				case "Unreleased", "Unplanned", "Proposal":
					return nil
				}
				if strings.Count(e.Milestone, ".") > 1 {
					return nil
				}
				ms := strings.TrimSuffix(e.Milestone, "Maybe")
				ms = strings.TrimSuffix(ms, "Early")
				was[ms] = true
			}
			return nil
		})
		if len(was) > 2 {
			var mss []string
			for ms := range was {
				mss = append(mss, ms)
			}
			sort.Slice(mss, func(i, j int) bool {
				if len(mss[i]) == len(mss[j]) {
					return mss[i] < mss[j]
				}
				return len(mss[i]) < len(mss[j])
			})
			matches = append(matches, match{
				url:   fmt.Sprintf("https://go.dev/issue/%d", gi.Number),
				title: fmt.Sprintf("%s - %v", gi.Title, mss),
				gi:    gi,
			})
		}
		return nil
	})
	sort.Slice(matches, func(i, j int) bool {
		return matches[i].title < matches[j].title
	})
	fmt.Printf("%d issues:\n", len(matches))
	for _, m := range matches {
		fmt.Printf("%-30s - %s\n", m.url, m.title)
		if !*dryRun {
			if err := b.setMilestone(ctx, b.gorepo.ID(), m.gi, unplanned); err != nil {
				return err
			}
		}
	}
	return nil
}

// freezeOldIssues locks any issue that's old and closed.
// (Otherwise people find ancient bugs via searches and start asking questions
// into a void and it's sad for everybody.)
// This method doesn't need to explicitly avoid edit wars with humans because
// it bails out if the issue was edited recently. A human unlocking an issue
// causes the updated time to bump, which means the bot wouldn't try to lock it
// again for another year.
func (b *gopherbot) freezeOldIssues(ctx context.Context) error {
	tooOld := time.Now().Add(-365 * 24 * time.Hour)
	return b.corpus.GitHub().ForeachRepo(func(repo *maintner.GitHubRepo) error {
		if !gardenIssues(repo) {
			return nil
		}
		if !repoHasLabel(repo, frozenDueToAge) {
			return nil
		}
		return b.foreachIssue(repo, closed, func(gi *maintner.GitHubIssue) error {
			if gi.Locked || gi.Updated.After(tooOld) {
				return nil
			}
			printIssue("freeze", repo.ID(), gi)
			if *dryRun {
				return nil
			}
			_, err := b.ghc.Issues.Lock(ctx, repo.ID().Owner, repo.ID().Repo, int(gi.Number), nil)
			if ge, ok := err.(*github.ErrorResponse); ok && ge.Response.StatusCode == http.StatusNotFound {
				// An issue can become 404 on GitHub due to being deleted or transferred. See go.dev/issue/30182.
				b.deletedIssues[githubIssue{repo.ID(), gi.Number}] = true
				return nil
			} else if err != nil {
				return err
			}
			return b.addLabel(ctx, repo.ID(), gi, frozenDueToAge)
		})
	})
}

// labelProposals adds the "Proposal" label and "Proposal" milestone
// to open issues with title beginning with "Proposal:". It tries not
// to get into an edit war with a human.
func (b *gopherbot) labelProposals(ctx context.Context) error {
	return b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		if !strings.HasPrefix(gi.Title, "proposal:") && !strings.HasPrefix(gi.Title, "Proposal:") {
			return nil
		}
		// Add Milestone if missing:
		if gi.Milestone.IsNone() && !gi.HasEvent("milestoned") && !gi.HasEvent("demilestoned") {
			if err := b.setMilestone(ctx, b.gorepo.ID(), gi, proposal); err != nil {
				return err
			}
		}
		// Add Proposal label if missing:
		if !gi.HasLabel("Proposal") && !gi.HasEvent("unlabeled") {
			if err := b.addLabel(ctx, b.gorepo.ID(), gi, "Proposal"); err != nil {
				return err
			}
		}

		// Remove NeedsDecision label if exists, but not for Go 2 issues:
		if !isGo2Issue(gi) && gi.HasLabel("NeedsDecision") && !gopherbotRemovedLabel(gi, "NeedsDecision") {
			if err := b.removeLabel(ctx, b.gorepo.ID(), gi, "NeedsDecision"); err != nil {
				return err
			}
		}
		return nil
	})
}

// gopherbotRemovedLabel reports whether gopherbot has
// previously removed label in the GitHub issue gi.
//
// Note that until golang.org/issue/28226 is resolved,
// there's a brief delay before maintner catches up on
// GitHub issue events and learns that it has happened.
func gopherbotRemovedLabel(gi *maintner.GitHubIssue, label string) bool {
	var hasRemoved bool
	gi.ForeachEvent(func(e *maintner.GitHubIssueEvent) error {
		if e.Actor != nil && e.Actor.ID == gopherbotGitHubID &&
			e.Type == "unlabeled" &&
			e.Label == label {
			hasRemoved = true
			return errStopIteration
		}
		return nil
	})
	return hasRemoved
}

// isGo2Issue reports whether gi seems like it's about Go 2, based on either labels or its title.
func isGo2Issue(gi *maintner.GitHubIssue) bool {
	if gi.HasLabel("Go2") {
		return true
	}
	if !strings.Contains(gi.Title, "2") {
		// Common case.
		return false
	}
	return strings.Contains(gi.Title, "Go 2") || strings.Contains(gi.Title, "go2") || strings.Contains(gi.Title, "Go2")
}

func (b *gopherbot) setSubrepoMilestones(ctx context.Context) error {
	return b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		if !gi.Milestone.IsNone() || gi.HasEvent("demilestoned") || gi.HasEvent("milestoned") {
			return nil
		}
		if !strings.HasPrefix(gi.Title, "x/") {
			return nil
		}
		pkg := gi.Title
		if colon := strings.IndexByte(pkg, ':'); colon >= 0 {
			pkg = pkg[:colon]
		}
		if sp := strings.IndexByte(pkg, ' '); sp >= 0 {
			pkg = pkg[:sp]
		}
		switch pkg {
		case "",
			"x/arch",
			"x/crypto/chacha20poly1305",
			"x/crypto/curve25519",
			"x/crypto/poly1305",
			"x/net/http2",
			"x/net/idna",
			"x/net/lif",
			"x/net/proxy",
			"x/net/route",
			"x/text/unicode/norm",
			"x/text/width":
			// These get vendored in. Don't mess with them.
			return nil
		case "x/vgo":
			// Handled by setMiscMilestones
			return nil
		}
		return b.setMilestone(ctx, b.gorepo.ID(), gi, unreleased)
	})
}

func (b *gopherbot) setMiscMilestones(ctx context.Context) error {
	return b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		if !gi.Milestone.IsNone() || gi.HasEvent("demilestoned") || gi.HasEvent("milestoned") {
			return nil
		}
		if strings.Contains(gi.Title, "gccgo") { // TODO: better gccgo bug report heuristic?
			return b.setMilestone(ctx, b.gorepo.ID(), gi, gccgo)
		}
		if strings.HasPrefix(gi.Title, "x/vgo") {
			return b.setMilestone(ctx, b.gorepo.ID(), gi, vgo)
		}
		if strings.HasPrefix(gi.Title, "x/vuln") {
			return b.setMilestone(ctx, b.gorepo.ID(), gi, vulnUnplanned)
		}
		return nil
	})
}

func (b *gopherbot) setVSCodeGoMilestones(ctx context.Context) error {
	vscode := b.corpus.GitHub().Repo("golang", "vscode-go")
	if vscode == nil {
		return nil
	}
	return b.foreachIssue(vscode, open, func(gi *maintner.GitHubIssue) error {
		if !gi.Milestone.IsNone() || gi.HasEvent("demilestoned") || gi.HasEvent("milestoned") {
			return nil
		}
		// Work-around golang/go#40640 by only milestoning new issues.
		if time.Since(gi.Created) > 24*time.Hour {
			return nil
		}
		return b.setMilestone(ctx, vscode.ID(), gi, vscodeUntriaged)
	})
}

func (b *gopherbot) labelBuildIssues(ctx context.Context) error {
	return b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		if !strings.HasPrefix(gi.Title, "x/build") || gi.HasLabel("Builders") || gi.HasEvent("unlabeled") {
			return nil
		}
		return b.addLabel(ctx, b.gorepo.ID(), gi, "Builders")
	})
}

func (b *gopherbot) labelCompilerRuntimeIssues(ctx context.Context) error {
	entries, err := getAllCodeOwners(ctx)
	if err != nil {
		return err
	}
	// Filter out any entries that don't contain compiler/runtime owners into
	// a set of compiler/runtime-owned packages whose names match the names
	// used in the issue tracker.
	crtPackages := make(map[string]struct{}) // Key is issue title prefix, like "cmd/compile" or "x/sys/unix."
	for pkg, entry := range entries {
		for _, owner := range entry.Primary {
			name := owner.GitHubUsername
			if name == "golang/compiler" || name == "golang/runtime" {
				crtPackages[owners.TranslatePathForIssues(pkg)] = struct{}{}
				break
			}
		}
	}
	return b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		if gi.HasLabel("compiler/runtime") || gi.HasEvent("unlabeled") {
			return nil
		}
		components := strings.SplitN(gi.Title, ":", 2)
		if len(components) != 2 {
			return nil
		}
		for _, p := range strings.Split(strings.TrimSpace(components[0]), ",") {
			if _, ok := crtPackages[strings.TrimSpace(p)]; !ok {
				continue
			}
			// TODO(mknyszek): Add this issue to the GitHub project as well.
			return b.addLabel(ctx, b.gorepo.ID(), gi, "compiler/runtime")
		}
		return nil
	})
}

func (b *gopherbot) labelMobileIssues(ctx context.Context) error {
	return b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		if !strings.HasPrefix(gi.Title, "x/mobile") || gi.HasLabel("mobile") || gi.HasEvent("unlabeled") {
			return nil
		}
		return b.addLabel(ctx, b.gorepo.ID(), gi, "mobile")
	})
}

func (b *gopherbot) labelDocumentationIssues(ctx context.Context) error {
	const documentation = "Documentation"
	return b.corpus.GitHub().ForeachRepo(func(repo *maintner.GitHubRepo) error {
		if !gardenIssues(repo) {
			return nil
		}
		if !repoHasLabel(repo, documentation) {
			return nil
		}
		return b.foreachIssue(repo, open, func(gi *maintner.GitHubIssue) error {
			if !isDocumentationTitle(gi.Title) || gi.HasLabel("Documentation") || gi.HasEvent("unlabeled") {
				return nil
			}
			return b.addLabel(ctx, repo.ID(), gi, documentation)
		})
	})
}

func (b *gopherbot) labelToolsIssues(ctx context.Context) error {
	return b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		if !strings.HasPrefix(gi.Title, "x/tools") || gi.HasLabel("Tools") || gi.HasEvent("unlabeled") {
			return nil
		}
		return b.addLabel(ctx, b.gorepo.ID(), gi, "Tools")
	})
}

func (b *gopherbot) labelWebsiteIssues(ctx context.Context) error {
	return b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		hasWebsiteTitle := strings.HasPrefix(gi.Title, "x/website:")
		if !hasWebsiteTitle || gi.HasLabel("website") || gi.HasEvent("unlabeled") {
			return nil
		}
		return b.addLabel(ctx, b.gorepo.ID(), gi, "website")
	})
}

func (b *gopherbot) labelPkgsiteIssues(ctx context.Context) error {
	return b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		hasPkgsiteTitle := strings.HasPrefix(gi.Title, "x/pkgsite:")
		if !hasPkgsiteTitle || gi.HasLabel("pkgsite") || gi.HasEvent("unlabeled") {
			return nil
		}
		return b.addLabel(ctx, b.gorepo.ID(), gi, "pkgsite")
	})
}

func (b *gopherbot) labelProxyIssues(ctx context.Context) error {
	return b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		hasProxyTitle := strings.Contains(gi.Title, "proxy.golang.org") || strings.Contains(gi.Title, "sum.golang.org") || strings.Contains(gi.Title, "index.golang.org")
		if !hasProxyTitle || gi.HasLabel("proxy.golang.org") || gi.HasEvent("unlabeled") {
			return nil
		}
		return b.addLabel(ctx, b.gorepo.ID(), gi, "proxy.golang.org")
	})
}

func (b *gopherbot) labelVulnIssues(ctx context.Context) error {
	return b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		hasVulnTitle := strings.HasPrefix(gi.Title, "x/vuln:") || strings.HasPrefix(gi.Title, "x/vuln/") ||
			strings.HasPrefix(gi.Title, "x/vulndb:") || strings.HasPrefix(gi.Title, "x/vulndb/")
		if !hasVulnTitle || gi.HasLabel("vulncheck or vulndb") || gi.HasEvent("unlabeled") {
			return nil
		}
		return b.addLabel(ctx, b.gorepo.ID(), gi, "vulncheck or vulndb")
	})
}

// handleGoplsIssues labels and asks for additional information on gopls issues.
//
// This is necessary because gopls issues often require additional information to diagnose,
// and we don't ask for this information in the Go issue template.
func (b *gopherbot) handleGoplsIssues(ctx context.Context) error {
	return b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		if !isGoplsTitle(gi.Title) || gi.HasLabel("gopls") || gi.HasEvent("unlabeled") {
			return nil
		}
		return b.addLabel(ctx, b.gorepo.ID(), gi, "gopls")
	})
}

func (b *gopherbot) handleTelemetryIssues(ctx context.Context) error {
	return b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		if !strings.HasPrefix(gi.Title, "x/telemetry") || gi.HasLabel("telemetry") || gi.HasEvent("unlabeled") {
			return nil
		}
		return b.addLabel(ctx, b.gorepo.ID(), gi, "telemetry")
	})
}

func (b *gopherbot) closeStaleWaitingForInfo(ctx context.Context) error {
	const waitingForInfo = "WaitingForInfo"
	now := time.Now()
	return b.corpus.GitHub().ForeachRepo(func(repo *maintner.GitHubRepo) error {
		if !gardenIssues(repo) {
			return nil
		}
		if !repoHasLabel(repo, waitingForInfo) {
			return nil
		}
		return b.foreachIssue(repo, open, func(gi *maintner.GitHubIssue) error {
			if !gi.HasLabel(waitingForInfo) {
				return nil
			}
			var waitStart time.Time
			gi.ForeachEvent(func(e *maintner.GitHubIssueEvent) error {
				if e.Type == "reopened" {
					// Ignore any previous WaitingForInfo label if it's reopend.
					waitStart = time.Time{}
					return nil
				}
				if e.Label == waitingForInfo {
					switch e.Type {
					case "unlabeled":
						waitStart = time.Time{}
					case "labeled":
						waitStart = e.Created
					}
					return nil
				}
				return nil
			})
			if waitStart.IsZero() {
				return nil
			}

			deadline := waitStart.AddDate(0, 1, 0) // 1 month
			if gi.HasLabel("CherryPickCandidate") || gi.HasLabel("CherryPickApproved") {
				// Cherry-pick issues may sometimes need to wait while
				// fixes get prepared and soak, so give them more time.
				deadline = waitStart.AddDate(0, 6, 0)
			}
			if repo.ID().Repo == "vscode-go" && gi.HasLabel("automatedReport") {
				// Automated issue reports have low response rates.
				// Apply shorter timeout.
				deadline = waitStart.AddDate(0, 0, 7)
			}
			if now.Before(deadline) {
				return nil
			}

			var lastOPComment time.Time
			gi.ForeachComment(func(c *maintner.GitHubComment) error {
				if c.User.ID == gi.User.ID {
					lastOPComment = c.Created
				}
				return nil
			})
			if lastOPComment.After(waitStart) {
				return nil
			}

			printIssue("close-stale-waiting-for-info", repo.ID(), gi)
			// TODO: write a task that reopens issues if the OP speaks up.
			if err := b.addGitHubComment(ctx, repo, gi.Number,
				"Timed out in state WaitingForInfo. Closing.\n\n(I am just a bot, though. Please speak up if this is a mistake or you have the requested information.)"); err != nil {
				return fmt.Errorf("b.addGitHubComment(_, %v, %v) = %w", repo.ID(), gi.Number, err)
			}
			return b.closeGitHubIssue(ctx, repo.ID(), gi.Number, notPlanned)
		})
	})
}

// cl2issue writes "Change https://go.dev/cl/NNNN mentions this issue"
// and the change summary on GitHub when a new Gerrit change references a GitHub issue.
func (b *gopherbot) cl2issue(ctx context.Context) error {
	monthAgo := time.Now().Add(-30 * 24 * time.Hour)
	return b.corpus.Gerrit().ForeachProjectUnsorted(func(gp *maintner.GerritProject) error {
		if gp.Server() != "go.googlesource.com" {
			return nil
		}
		return gp.ForeachCLUnsorted(func(cl *maintner.GerritCL) error {
			if cl.Meta.Commit.AuthorTime.Before(monthAgo) {
				// If the CL was last updated over a
				// month ago, assume (as an
				// optimization) that gopherbot
				// already processed this issue.
				return nil
			}
			for _, ref := range cl.GitHubIssueRefs {
				if !gardenIssues(ref.Repo) {
					continue
				}
				gi := ref.Repo.Issue(ref.Number)
				if gi == nil || gi.NotExist || gi.PullRequest || gi.Locked || b.deletedIssues[githubIssue{ref.Repo.ID(), gi.Number}] {
					continue
				}
				hasComment := false
				substr := fmt.Sprintf("%d mentions this issue", cl.Number)
				gi.ForeachComment(func(c *maintner.GitHubComment) error {
					if strings.Contains(c.Body, substr) {
						hasComment = true
						return errStopIteration
					}
					return nil
				})
				if hasComment {
					continue
				}
				printIssue("cl2issue", ref.Repo.ID(), gi)
				msg := fmt.Sprintf("Change https://go.dev/cl/%d mentions this issue: `%s`", cl.Number, cl.Commit.Summary())
				if err := b.addGitHubComment(ctx, ref.Repo, gi.Number, msg); err != nil {
					return err
				}
			}
			return nil
		})
	})
}

// canonicalLabelName returns "needsfix" for "needs-fix" or "NeedsFix"
// in prep for future label renaming.
func canonicalLabelName(s string) string {
	return strings.Replace(strings.ToLower(s), "-", "", -1)
}

// If an issue has multiple "needs" labels, remove all but the most recent.
// These were originally called NeedsFix, NeedsDecision, and NeedsInvestigation,
// but are being renamed to "needs-foo".
func (b *gopherbot) updateNeeds(ctx context.Context) error {
	return b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		var numNeeds int
		if gi.Labels[needsDecisionID] != nil {
			numNeeds++
		}
		if gi.Labels[needsFixID] != nil {
			numNeeds++
		}
		if gi.Labels[needsInvestigationID] != nil {
			numNeeds++
		}
		if numNeeds <= 1 {
			return nil
		}

		labels := map[string]int{} // lowercase no-hyphen "needsfix" -> position
		var pos, maxPos int
		gi.ForeachEvent(func(e *maintner.GitHubIssueEvent) error {
			var add bool
			switch e.Type {
			case "labeled":
				add = true
			case "unlabeled":
			default:
				return nil
			}
			if !strings.HasPrefix(e.Label, "Needs") && !strings.HasPrefix(e.Label, "needs-") {
				return nil
			}
			key := canonicalLabelName(e.Label)
			pos++
			if add {
				labels[key] = pos
				maxPos = pos
			} else {
				delete(labels, key)
			}
			return nil
		})
		if len(labels) <= 1 {
			return nil
		}

		// Remove any label that's not the newest (added in
		// last position).
		for _, lab := range gi.Labels {
			key := canonicalLabelName(lab.Name)
			if !strings.HasPrefix(key, "needs") || labels[key] == maxPos {
				continue
			}
			printIssue("updateneeds", b.gorepo.ID(), gi)
			fmt.Printf("\t... removing label %q\n", lab.Name)
			if err := b.removeLabel(ctx, b.gorepo.ID(), gi, lab.Name); err != nil {
				return err
			}
		}
		return nil
	})
}

// TODO: Improve this message. Some ideas:
//
// Provide more helpful info? Amend, don't add 2nd commit, link to a review guide?
// Make this a template? May want to provide more dynamic information in the future.
// Only show freeze message during freeze.
const (
	congratsSentence = `Congratulations on opening your first change. Thank you for your contribution!`

	defaultCongratsMsg = congratsSentence + `

Next steps:
A maintainer will review your change and provide feedback. See
https://go.dev/doc/contribute#review for more info and tips to get your
patch through code review.

Most changes in the Go project go through a few rounds of revision. This can be
surprising to people new to the project. The careful, iterative review process
is our way of helping mentor contributors and ensuring that their contributions
have a lasting impact.`

	// Not all x/ repos are subject to the freeze, and so shouldn't get the
	// warning about it. See isSubjectToFreeze for the complete list.
	freezeCongratsMsg = defaultCongratsMsg + `

During May-July and Nov-Jan the Go project is in a code freeze, during which
little code gets reviewed or merged. If a reviewer responds with a comment like
R=go1.11 or adds a tag like "wait-release", it means that this CL will be
reviewed as part of the next development cycle. See https://go.dev/s/release
for more details.`
)

// If messages containing any of the sentences in this array have been posted
// on a CL, don't post again. If you amend the message even slightly, please
// prepend the new message to this list, to avoid re-spamming people.
//
// The first message is the "current" message.
var oldCongratsMsgs = []string{
	congratsSentence,
	`It's your first ever CL! Congrats, and thanks for sending!`,
}

// isSubjectToFreeze returns true if a repository is subject to the release
// freeze. x/ repos can be subject if they are vendored into golang/go.
func isSubjectToFreeze(repo string) bool {
	switch repo {
	case "go": // main repo
		return true
	case "crypto", "net", "sys", "text": // vendored x/ repos
		return true
	}
	return false
}

// Don't want to congratulate people on CL's they submitted a year ago.
var congratsEpoch = time.Date(2017, 6, 17, 0, 0, 0, 0, time.UTC)

func (b *gopherbot) congratulateNewContributors(ctx context.Context) error {
	cls := make(map[string]*maintner.GerritCL)
	b.corpus.Gerrit().ForeachProjectUnsorted(func(gp *maintner.GerritProject) error {
		if gp.Server() != "go.googlesource.com" {
			return nil
		}
		return gp.ForeachCLUnsorted(func(cl *maintner.GerritCL) error {
			// CLs can be returned by maintner in any order. Note also that
			// Gerrit CL numbers are sparse (CL N does not guarantee that CL N-1
			// exists) and Gerrit issues CL's out of order - it may issue CL N,
			// then CL (N - 18), then CL (N - 40).
			if b.knownContributors == nil {
				b.knownContributors = make(map[string]bool)
			}
			if cl.Commit == nil {
				return nil
			}
			email := cl.Commit.Author.Email()
			if email == "" {
				email = cl.Commit.Author.Str
			}
			if b.knownContributors[email] {
				return nil
			}
			if cls[email] != nil {
				// this person has multiple CLs; not a new contributor.
				b.knownContributors[email] = true
				delete(cls, email)
				return nil
			}
			cls[email] = cl
			return nil
		})
	})
	for email, cl := range cls {
		// See golang.org/issue/23865
		if cl.Branch() == "refs/meta/config" {
			b.knownContributors[email] = true
			continue
		}
		if cl.Commit == nil || cl.Commit.CommitTime.Before(congratsEpoch) {
			b.knownContributors[email] = true
			continue
		}
		if cl.Status == "merged" {
			b.knownContributors[email] = true
			continue
		}
		foundMessage := false
		congratulatoryMessage := defaultCongratsMsg
		if isSubjectToFreeze(cl.Project.Project()) {
			congratulatoryMessage = freezeCongratsMsg
		}
		for i := range cl.Messages {
			// TODO: once gopherbot starts posting these messages and we
			// have the author's name for Gopherbot, check the author name
			// matches as well.
			for j := range oldCongratsMsgs {
				// Message looks something like "Patch set X:\n\n(our text)"
				if strings.Contains(cl.Messages[i].Message, oldCongratsMsgs[j]) {
					foundMessage = true
					break
				}
			}
			if foundMessage {
				break
			}
		}

		if foundMessage {
			b.knownContributors[email] = true
			continue
		}
		// Don't add all of the old congratulatory messages here, since we've
		// already checked for them above.
		opts := &gerritCommentOpts{
			OldPhrases: []string{congratulatoryMessage},
		}
		err := b.addGerritComment(ctx, cl.ChangeID(), congratulatoryMessage, opts)
		if err != nil {
			return fmt.Errorf("could not add comment to golang.org/cl/%d: %v", cl.Number, err)
		}
		b.knownContributors[email] = true
	}
	return nil
}

// unwaitCLs removes wait-* hashtags from CLs.
func (b *gopherbot) unwaitCLs(ctx context.Context) error {
	return b.corpus.Gerrit().ForeachProjectUnsorted(func(gp *maintner.GerritProject) error {
		if gp.Server() != "go.googlesource.com" {
			return nil
		}
		return gp.ForeachOpenCL(func(cl *maintner.GerritCL) error {
			tags := cl.Meta.Hashtags()
			if tags.Len() == 0 {
				return nil
			}
			// If the CL is tagged "wait-author", remove
			// that tag if the author has replied since
			// the last time the "wait-author" tag was
			// added.
			if tags.Contains("wait-author") {
				// Figure out the last index at which "wait-author" was added.
				waitAuthorIndex := -1
				for i := len(cl.Metas) - 1; i >= 0; i-- {
					if cl.Metas[i].HashtagsAdded().Contains("wait-author") {
						waitAuthorIndex = i
						break
					}
				}

				// Find out whether the author has replied since.
				authorEmail := cl.Metas[0].Commit.Author.Email() // Equivalent to "{{cl.OwnerID}}@62eb7196-b449-3ce5-99f1-c037f21e1705".
				hasReplied := false
				for _, m := range cl.Metas[waitAuthorIndex+1:] {
					if m.Commit.Author.Email() == authorEmail {
						hasReplied = true
						break
					}
				}
				if hasReplied {
					log.Printf("https://go.dev/cl/%d -- remove wait-author; reply from %s", cl.Number, cl.Owner())
					err := b.onLatestCL(ctx, cl, func() error {
						if *dryRun {
							log.Printf("[dry run] would remove hashtag 'wait-author' from CL %d", cl.Number)
							return nil
						}
						_, err := b.gerrit.RemoveHashtags(ctx, fmt.Sprint(cl.Number), "wait-author")
						if err != nil {
							log.Printf("https://go.dev/cl/%d: error removing wait-author: %v", cl.Number, err)
							return err
						}
						log.Printf("https://go.dev/cl/%d: removed wait-author", cl.Number)
						return nil
					})
					if err != nil {
						return err
					}
				}
			}
			return nil
		})
	})
}

// onLatestCL checks whether cl's metadata is up to date with Gerrit's
// upstream data and, if so, returns f(). If it's out of date, it does
// nothing more and returns nil.
func (b *gopherbot) onLatestCL(ctx context.Context, cl *maintner.GerritCL, f func() error) error {
	ci, err := b.gerrit.GetChangeDetail(ctx, fmt.Sprint(cl.Number), gerrit.QueryChangesOpt{Fields: []string{"MESSAGES"}})
	if err != nil {
		return err
	}
	if len(ci.Messages) == 0 {
		log.Printf("onLatestCL: CL %d has no messages. Odd. Ignoring.", cl.Number)
		return nil
	}
	latestGerritID := ci.Messages[len(ci.Messages)-1].ID
	// Check all metas and not just the latest, because there are some meta commits
	// that don't have a corresponding message in the Gerrit REST API response.
	for i := len(cl.Metas) - 1; i >= 0; i-- {
		metaHash := cl.Metas[i].Commit.Hash.String()
		if metaHash == latestGerritID {
			// latestGerritID is contained by maintner metadata for this CL, so run f().
			return f()
		}
	}
	log.Printf("onLatestCL: maintner metadata for CL %d is behind; skipping action for now.", cl.Number)
	return nil
}

// fetchReleases returns the two most recent major Go 1.x releases, and
// the next upcoming release, sorted and formatted like []string{"1.9", "1.10", "1.11"}.
// It also returns the next minor release for each major release,
// like map[string]string{"1.9": "1.9.7", "1.10": "1.10.4", "1.11": "1.11.1"}.
//
// The data returned is fetched from Maintner Service occasionally
// and cached for some time.
func (b *gopherbot) fetchReleases(ctx context.Context) (major []string, nextMinor map[string]string, _ error) {
	b.releases.Lock()
	defer b.releases.Unlock()

	if expiry := b.releases.lastUpdate.Add(10 * time.Minute); time.Now().Before(expiry) {
		return b.releases.major, b.releases.nextMinor, nil
	}

	ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
	defer cancel()
	resp, err := b.mc.ListGoReleases(ctx, &apipb.ListGoReleasesRequest{})
	if err != nil {
		return nil, nil, err
	}
	rs := resp.Releases // Supported Go releases, sorted with latest first.

	nextMinor = make(map[string]string)
	for i := len(rs) - 1; i >= 0; i-- {
		x, y, z := rs[i].Major, rs[i].Minor, rs[i].Patch
		major = append(major, fmt.Sprintf("%d.%d", x, y))
		nextMinor[fmt.Sprintf("%d.%d", x, y)] = fmt.Sprintf("%d.%d.%d", x, y, z+1)
	}
	// Include the next release in the list of major releases.
	if len(rs) > 0 {
		// Assume the next major release after Go X.Y is Go X.(Y+1). This is true more often than not.
		nextX, nextY := rs[0].Major, rs[0].Minor+1
		major = append(major, fmt.Sprintf("%d.%d", nextX, nextY))
		nextMinor[fmt.Sprintf("%d.%d", nextX, nextY)] = fmt.Sprintf("%d.%d.1", nextX, nextY)
	}

	b.releases.major = major
	b.releases.nextMinor = nextMinor
	b.releases.lastUpdate = time.Now()

	return major, nextMinor, nil
}

// openCherryPickIssues opens CherryPickCandidate issues for backport when
// asked on the main issue.
func (b *gopherbot) openCherryPickIssues(ctx context.Context) error {
	return b.foreachIssue(b.gorepo, open|closed|includePRs, func(gi *maintner.GitHubIssue) error {
		if gi.HasLabel("CherryPickApproved") && gi.HasLabel("CherryPickCandidate") {
			if err := b.removeLabel(ctx, b.gorepo.ID(), gi, "CherryPickCandidate"); err != nil {
				return err
			}
		}
		if gi.Locked || gi.PullRequest {
			return nil
		}
		var backportComment *maintner.GitHubComment
		if err := gi.ForeachComment(func(c *maintner.GitHubComment) error {
			if strings.HasPrefix(c.Body, "Backport issue(s) opened") {
				backportComment = nil
				return errStopIteration
			}
			body := strings.ToLower(c.Body)
			if strings.Contains(body, "@gopherbot") &&
				strings.Contains(body, "please") &&
				strings.Contains(body, "backport") {
				backportComment = c
			}
			return nil
		}); err != nil && err != errStopIteration {
			return err
		}
		if backportComment == nil {
			return nil
		}

		// Figure out releases to open backport issues for.
		var selectedReleases []string
		majorReleases, _, err := b.fetchReleases(ctx)
		if err != nil {
			return err
		}
		for _, r := range majorReleases {
			if strings.Contains(backportComment.Body, r) {
				selectedReleases = append(selectedReleases, r)
			}
		}
		if len(selectedReleases) == 0 {
			// Only backport to major releases unless explicitly
			// asked to backport to the upcoming release.
			selectedReleases = majorReleases[:len(majorReleases)-1]
		}

		// Figure out extra labels to include from the main issue.
		// Only copy a subset that's relevant to backport issue management.
		var extraLabels []string
		for _, l := range [...]string{
			"Security",
			"GoCommand",
			"Testing",
		} {
			if gi.HasLabel(l) {
				extraLabels = append(extraLabels, l)
			}
		}

		// Open backport issues.
		var openedIssues []string
		for _, rel := range selectedReleases {
			printIssue("open-backport-issue-"+rel, b.gorepo.ID(), gi)
			id, err := b.createGitHubIssue(ctx,
				fmt.Sprintf("%s [%s backport]", gi.Title, rel),
				fmt.Sprintf("@%s requested issue #%d to be considered for backport to the next %s minor release.\n\n%s\n",
					backportComment.User.Login, gi.Number, rel, blockqoute(backportComment.Body)),
				append([]string{"CherryPickCandidate"}, extraLabels...), backportComment.Created)
			if err != nil {
				return err
			}
			openedIssues = append(openedIssues, fmt.Sprintf("#%d (for %s)", id, rel))
		}
		return b.addGitHubComment(ctx, b.gorepo, gi.Number, fmt.Sprintf("Backport issue(s) opened: %s.\n\nRemember to create the cherry-pick CL(s) as soon as the patch is submitted to master, according to https://go.dev/wiki/MinorReleases.", strings.Join(openedIssues, ", ")))
	})
}

// setMinorMilestones applies the next minor release milestone
// to issues with [1.X backport] in the title.
func (b *gopherbot) setMinorMilestones(ctx context.Context) error {
	majorReleases, nextMinor, err := b.fetchReleases(ctx)
	if err != nil {
		return err
	}
	return b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		if !gi.Milestone.IsNone() || gi.HasEvent("demilestoned") || gi.HasEvent("milestoned") {
			return nil
		}
		var majorRel string
		for _, r := range majorReleases {
			if strings.Contains(gi.Title, "backport") && strings.HasSuffix(gi.Title, "["+r+" backport]") {
				majorRel = r
			}
		}
		if majorRel == "" {
			return nil
		}
		if _, ok := nextMinor[majorRel]; !ok {
			return fmt.Errorf("internal error: fetchReleases returned majorReleases=%q nextMinor=%q, and nextMinor doesn't have %q", majorReleases, nextMinor, majorRel)
		}
		lowerTitle := "go" + nextMinor[majorRel]
		var nextMinorMilestone milestone
		if b.gorepo.ForeachMilestone(func(m *maintner.GitHubMilestone) error {
			if m.Closed || strings.ToLower(m.Title) != lowerTitle {
				return nil
			}
			nextMinorMilestone = milestone{
				Number: int(m.Number),
				Name:   m.Title,
			}
			return errStopIteration
		}); nextMinorMilestone == (milestone{}) {
			// Fail silently, the milestone might not exist yet.
			log.Printf("Failed to apply minor release milestone to issue %d", gi.Number)
			return nil
		}
		return b.setMilestone(ctx, b.gorepo.ID(), gi, nextMinorMilestone)
	})
}

// closeCherryPickIssues closes cherry-pick issues when CLs are merged to
// release branches, as GitHub only does that on merge to master.
func (b *gopherbot) closeCherryPickIssues(ctx context.Context) error {
	cherryPickIssues := make(map[int32]*maintner.GitHubIssue) // by GitHub Issue Number
	b.foreachIssue(b.gorepo, open, func(gi *maintner.GitHubIssue) error {
		if gi.Milestone.IsNone() || gi.HasEvent("reopened") {
			return nil
		}
		if !strings.HasPrefix(gi.Milestone.Title, "Go") {
			return nil
		}
		cherryPickIssues[gi.Number] = gi
		return nil
	})
	monthAgo := time.Now().Add(-30 * 24 * time.Hour)
	return b.corpus.Gerrit().ForeachProjectUnsorted(func(gp *maintner.GerritProject) error {
		if gp.Server() != "go.googlesource.com" {
			return nil
		}
		return gp.ForeachCLUnsorted(func(cl *maintner.GerritCL) error {
			if cl.Commit.CommitTime.Before(monthAgo) {
				// If the CL was last updated over a month ago, assume (as an
				// optimization) that gopherbot already processed this CL.
				return nil
			}
			if cl.Status != "merged" || cl.Private || !strings.HasPrefix(cl.Branch(), "release-branch.") {
				return nil
			}
			clBranchVersion := cl.Branch()[len("release-branch."):] // "go1.11" or "go1.12".
			for _, ref := range cl.GitHubIssueRefs {
				if ref.Repo != b.gorepo {
					continue
				}
				gi, ok := cherryPickIssues[ref.Number]
				if !ok {
					continue
				}
				if !strutil.HasPrefixFold(gi.Milestone.Title, clBranchVersion) {
					// This issue's milestone (e.g., "Go1.11.6", "Go1.12", "Go1.12.1", etc.)
					// doesn't match the CL branch goX.Y version, so skip it.
					continue
				}
				printIssue("close-cherry-pick", ref.Repo.ID(), gi)
				if err := b.addGitHubComment(ctx, ref.Repo, gi.Number, fmt.Sprintf(
					"Closed by merging %s to %s.", cl.Commit.Hash, cl.Branch())); err != nil {
					return err
				}
				return b.closeGitHubIssue(ctx, ref.Repo.ID(), gi.Number, completed)
			}
			return nil
		})
	})
}

type labelCommand struct {
	action  string    // "add" or "remove"
	label   string    // the label name
	created time.Time // creation time of the comment containing the command
	noop    bool      // whether to apply the command or not
}

// applyLabelsFromComments looks within open GitHub issues for commands to add or
// remove labels. Anyone can use the /label <label> or /unlabel <label> commands.
func (b *gopherbot) applyLabelsFromComments(ctx context.Context) error {
	return b.corpus.GitHub().ForeachRepo(func(repo *maintner.GitHubRepo) error {
		if !gardenIssues(repo) {
			return nil
		}

		allLabels := make(map[string]string) // lowercase label name -> proper casing
		repo.ForeachLabel(func(gl *maintner.GitHubLabel) error {
			allLabels[strings.ToLower(gl.Name)] = gl.Name
			return nil
		})

		return b.foreachIssue(repo, open|includePRs, func(gi *maintner.GitHubIssue) error {
			var cmds []labelCommand

			cmds = append(cmds, labelCommandsFromBody(gi.Body, gi.Created)...)
			gi.ForeachComment(func(gc *maintner.GitHubComment) error {
				cmds = append(cmds, labelCommandsFromBody(gc.Body, gc.Created)...)
				return nil
			})

			for i, c := range cmds {
				// Does the label even exist? If so, use the proper capitalization.
				// If it doesn't exist, the command is a no-op.
				if l, ok := allLabels[c.label]; ok {
					cmds[i].label = l
				} else {
					cmds[i].noop = true
					continue
				}

				// If any action has been taken on the label since the comment containing
				// the command to add or remove it, then it should be a no-op.
				gi.ForeachEvent(func(ge *maintner.GitHubIssueEvent) error {
					if (ge.Type == "unlabeled" || ge.Type == "labeled") &&
						strings.ToLower(ge.Label) == c.label &&
						ge.Created.After(c.created) {
						cmds[i].noop = true
						return errStopIteration
					}
					return nil
				})
			}

			toAdd, toRemove := mutationsFromCommands(cmds)
			if err := b.addLabels(ctx, repo.ID(), gi, toAdd); err != nil {
				log.Printf("Unable to add labels (%v) to issue %d: %v", toAdd, gi.Number, err)
			}
			if err := b.removeLabels(ctx, repo.ID(), gi, toRemove); err != nil {
				log.Printf("Unable to remove labels (%v) from issue %d: %v", toRemove, gi.Number, err)
			}

			return nil
		})
	})
}

// labelCommandsFromBody returns a slice of commands inferred by the given body text.
// The format of commands is:
// @gopherbot[,] [please] [add|remove] <label>[{,|;} label... and remove <label>...]
// Omission of add or remove will default to adding a label.
func labelCommandsFromBody(body string, created time.Time) []labelCommand {
	if !strutil.ContainsFold(body, "@gopherbot") {
		return nil
	}
	var cmds []labelCommand
	lines := strings.Split(body, "\n")
	for _, l := range lines {
		if !strutil.ContainsFold(l, "@gopherbot") {
			continue
		}
		l = strings.ToLower(l)
		scanner := bufio.NewScanner(strings.NewReader(l))
		scanner.Split(bufio.ScanWords)
		var (
			add      strings.Builder
			remove   strings.Builder
			inRemove bool
		)
		for scanner.Scan() {
			switch scanner.Text() {
			case "@gopherbot", "@gopherbot,", "@gopherbot:", "please", "and", "label", "labels":
				continue
			case "add":
				inRemove = false
				continue
			case "remove", "unlabel":
				inRemove = true
				continue
			}

			if inRemove {
				remove.WriteString(scanner.Text())
				remove.WriteString(" ") // preserve whitespace within labels
			} else {
				add.WriteString(scanner.Text())
				add.WriteString(" ") // preserve whitespace within labels
			}
		}
		if add.Len() > 0 {
			cmds = append(cmds, labelCommands(add.String(), "add", created)...)
		}
		if remove.Len() > 0 {
			cmds = append(cmds, labelCommands(remove.String(), "remove", created)...)
		}
	}
	return cmds
}

// labelCommands returns a slice of commands for the given action and string of
// text following commands like @gopherbot add/remove.
func labelCommands(s, action string, created time.Time) []labelCommand {
	var cmds []labelCommand
	f := func(c rune) bool {
		return c != '-' && !unicode.IsLetter(c) && !unicode.IsNumber(c) && !unicode.IsSpace(c)
	}
	for _, label := range strings.FieldsFunc(s, f) {
		label = strings.TrimSpace(label)
		if label == "" {
			continue
		}
		cmds = append(cmds, labelCommand{action: action, label: label, created: created})
	}
	return cmds
}

// mutationsFromCommands returns two sets of labels to add and remove based on
// the given cmds.
func mutationsFromCommands(cmds []labelCommand) (add, remove []string) {
	// Split the labels into what to add and what to remove.
	// Account for two opposing commands that have yet to be applied canceling
	// each other out.
	var (
		toAdd    map[string]bool
		toRemove map[string]bool
	)
	for _, c := range cmds {
		if c.noop {
			continue
		}
		switch c.action {
		case "add":
			if toRemove[c.label] {
				delete(toRemove, c.label)
				continue
			}
			if toAdd == nil {
				toAdd = make(map[string]bool)
			}
			toAdd[c.label] = true
		case "remove":
			if toAdd[c.label] {
				delete(toAdd, c.label)
				continue
			}
			if toRemove == nil {
				toRemove = make(map[string]bool)
			}
			toRemove[c.label] = true
		default:
			log.Printf("Invalid label action type: %q", c.action)
		}
	}

	for l := range toAdd {
		if toAdd[l] && !labelChangeDisallowed(l, "add") {
			add = append(add, l)
		}
	}

	for l := range toRemove {
		if toRemove[l] && !labelChangeDisallowed(l, "remove") {
			remove = append(remove, l)
		}
	}
	return add, remove
}

// labelChangeDisallowed reports whether an action on the given label is
// forbidden via gopherbot.
func labelChangeDisallowed(label, action string) bool {
	if action == "remove" && label == "Security" {
		return true
	}
	for _, prefix := range []string{
		"CherryPick",
		"cla:",
		"Proposal-",
	} {
		if strings.HasPrefix(label, prefix) {
			return true
		}
	}
	return false
}

// assignReviewersOptOut lists contributors who have opted out from
// having reviewers automatically added to their CLs.
var assignReviewersOptOut = map[string]bool{
	"mdempsky@google.com": true,
}

// assignReviewersToCLs looks for CLs with no humans in the reviewer or CC fields
// that have been open for a short amount of time (enough of a signal that the
// author does not intend to add anyone to the review), then assigns reviewers/CCs
// using the go.dev/s/owners API.
func (b *gopherbot) assignReviewersToCLs(ctx context.Context) error {
	const tagNoOwners = "no-owners"
	b.corpus.Gerrit().ForeachProjectUnsorted(func(gp *maintner.GerritProject) error {
		if gp.Project() == "scratch" || gp.Server() != "go.googlesource.com" {
			return nil
		}
		gp.ForeachOpenCL(func(cl *maintner.GerritCL) error {
			if cl.Private || cl.WorkInProgress() || time.Since(cl.Created) < 10*time.Minute {
				return nil
			}
			if assignReviewersOptOut[cl.Owner().Email()] {
				return nil
			}

			// Don't auto-assign reviewers to CLs on shared branches;
			// the presumption is that developers there will know which
			// reviewers to assign.
			if strings.HasPrefix(cl.Branch(), "dev.") {
				return nil
			}

			tags := cl.Meta.Hashtags()
			if tags.Contains(tagNoOwners) {
				return nil
			}

			gc := gerritChange{gp.Project(), cl.Number}
			if b.deletedChanges[gc] {
				return nil
			}
			if strutil.ContainsFold(cl.Commit.Msg, "do not submit") || strutil.ContainsFold(cl.Commit.Msg, "do not review") {
				return nil
			}

			currentReviewers, ok := b.humanReviewersOnChange(ctx, gc, cl)
			if ok {
				return nil
			}
			log.Printf("humanReviewersOnChange reported insufficient reviewers or CC on CL %d, attempting to add some", cl.Number)

			changeURL := fmt.Sprintf("https://go-review.googlesource.com/c/%s/+/%d", gp.Project(), cl.Number)
			files, err := b.gerrit.ListFiles(ctx, gc.ID(), cl.Commit.Hash.String())
			if err != nil {
				log.Printf("Could not get change %+v: %v", gc, err)
				if httpErr, ok := err.(*gerrit.HTTPError); ok && httpErr.Res.StatusCode == http.StatusNotFound {
					b.deletedChanges[gc] = true
				}
				return nil
			}

			var paths []string
			for f := range files {
				if f == "/COMMIT_MSG" {
					continue
				}
				paths = append(paths, gp.Project()+"/"+f)
			}

			entries, err := getCodeOwners(ctx, paths)
			if err != nil {
				log.Printf("Could not get owners for change %s: %v", changeURL, err)
				return nil
			}

			// Remove owners that can't be reviewers.
			entries = filterGerritOwners(entries)

			authorEmail := cl.Commit.Author.Email()
			merged := mergeOwnersEntries(entries, authorEmail)
			if len(merged.Primary) == 0 && len(merged.Secondary) == 0 {
				// No owners found for the change. Add the #no-owners tag.
				log.Printf("Adding no-owners tag to change %s...", changeURL)
				if *dryRun {
					return nil
				}
				if _, err := b.gerrit.AddHashtags(ctx, gc.ID(), tagNoOwners); err != nil {
					log.Printf("Could not add hashtag to change %q: %v", gc.ID(), err)
					return nil
				}
				return nil
			}

			// Assign reviewers.
			var review gerrit.ReviewInput
			for _, owner := range merged.Primary {
				review.Reviewers = append(review.Reviewers, gerrit.ReviewerInput{Reviewer: owner.GerritEmail})
			}
			for _, owner := range merged.Secondary {
				review.Reviewers = append(review.Reviewers, gerrit.ReviewerInput{Reviewer: owner.GerritEmail, State: "CC"})
			}

			// If the reviewers that would be set are the same as the existing
			// reviewers (minus the bots), there is no work to be done.
			if sameReviewers(currentReviewers, review) {
				log.Printf("Setting review %+v on %s would have no effect, continuing", review, changeURL)
				return nil
			}
			if *dryRun {
				log.Printf("[dry run] Would set review on %s: %+v", changeURL, review)
				return nil
			}
			log.Printf("Setting review on %s: %+v", changeURL, review)
			if err := b.gerrit.SetReview(ctx, gc.ID(), "current", review); err != nil {
				log.Printf("Could not set review for change %q: %v", gc.ID(), err)
				return nil
			}
			return nil
		})
		return nil
	})
	return nil
}

func sameReviewers(reviewers []string, review gerrit.ReviewInput) bool {
	if len(reviewers) != len(review.Reviewers) {
		return false
	}
	sort.Strings(reviewers)
	var people []*gophers.Person
	for _, id := range reviewers {
		p := gophers.GetPerson(fmt.Sprintf("%s%s", id, gerritInstanceID))
		// If an existing reviewer is not known to us, we have no way of
		// checking if these reviewer lists are identical.
		if p == nil {
			return false
		}
		people = append(people, p)
	}
	sort.Slice(review.Reviewers, func(i, j int) bool {
		return review.Reviewers[i].Reviewer < review.Reviewers[j].Reviewer
	})
	// Check if any of the person's emails match the expected reviewer email.
outer:
	for i, p := range people {
		reviewerEmail := review.Reviewers[i].Reviewer
		for _, email := range p.Emails {
			if email == reviewerEmail {
				continue outer
			}
		}
		return false
	}
	return true
}

// abandonScratchReviews abandons Gerrit CLs in the "scratch" project if they've been open for over a week.
func (b *gopherbot) abandonScratchReviews(ctx context.Context) error {
	tooOld := time.Now().Add(-24 * time.Hour * 7)
	return b.corpus.Gerrit().ForeachProjectUnsorted(func(gp *maintner.GerritProject) error {
		if gp.Project() != "scratch" || gp.Server() != "go.googlesource.com" {
			return nil
		}
		return gp.ForeachOpenCL(func(cl *maintner.GerritCL) error {
			if b.deletedChanges[gerritChange{gp.Project(), cl.Number}] || !cl.Meta.Commit.CommitTime.Before(tooOld) {
				return nil
			}
			if *dryRun {
				log.Printf("[dry-run] would've closed scratch CL https://go.dev/cl/%d ...", cl.Number)
				return nil
			}
			log.Printf("closing scratch CL https://go.dev/cl/%d ...", cl.Number)
			err := b.gerrit.AbandonChange(ctx, fmt.Sprint(cl.Number), "Auto-abandoning old scratch review.")
			if err != nil && strings.Contains(err.Error(), "404 Not Found") {
				return nil
			}
			return err
		})
	})
}

func (b *gopherbot) whoNeedsAccess(ctx context.Context) error {
	// We only run this task if it was explicitly requested via
	// the --only-run flag.
	if *onlyRun == "" {
		return nil
	}
	level := map[int64]int{} // gerrit id -> 1 for try, 2 for submit
	ais, err := b.gerrit.GetGroupMembers(ctx, "may-start-trybots")
	if err != nil {
		return err
	}
	for _, ai := range ais {
		level[ai.NumericID] = 1
	}
	ais, err = b.gerrit.GetGroupMembers(ctx, "approvers")
	if err != nil {
		return err
	}
	for _, ai := range ais {
		level[ai.NumericID] = 2
	}

	quarterAgo := time.Now().Add(-90 * 24 * time.Hour)
	missing := map[string]int{} // "only level N: $WHO" -> number of CLs for that user
	err = b.corpus.Gerrit().ForeachProjectUnsorted(func(gp *maintner.GerritProject) error {
		if gp.Server() != "go.googlesource.com" {
			return nil
		}
		return gp.ForeachCLUnsorted(func(cl *maintner.GerritCL) error {
			if cl.Meta.Commit.AuthorTime.Before(quarterAgo) {
				return nil
			}
			authorID := int64(cl.OwnerID())
			if authorID == -1 {
				return nil
			}
			if level[authorID] == 2 {
				return nil
			}
			missing[fmt.Sprintf("only level %d: %v", level[authorID], cl.Commit.Author)]++
			return nil
		})
	})
	if err != nil {
		return err
	}
	var people []string
	for who := range missing {
		people = append(people, who)
	}
	sort.Slice(people, func(i, j int) bool { return missing[people[j]] < missing[people[i]] })
	fmt.Println("Number of CLs created in last 90 days | Access (0=none, 1=trybots) | Author")
	for i, who := range people {
		num := missing[who]
		if num < 3 {
			break
		}
		fmt.Printf("%3d: %s\n", num, who)
		if i == 20 {
			break
		}
	}
	return nil
}

// humanReviewersOnChange reports whether there is (or was) a sufficient
// number of human reviewers in the given change, and returns the IDs of
// the current human reviewers. It includes reviewers in REVIEWER and CC
// states.
//
// The given gerritChange works as a key for deletedChanges.
func (b *gopherbot) humanReviewersOnChange(ctx context.Context, change gerritChange, cl *maintner.GerritCL) ([]string, bool) {
	// The CL's owner will be GerritBot if it is imported from a PR.
	// In that case, if the CL's author has a Gerrit account, they will be
	// added as a reviewer (go.dev/issue/30265). Otherwise, no reviewers
	// will be added. Work around this by requiring 2 human reviewers on PRs.
	ownerID := strconv.Itoa(cl.OwnerID())
	isPR := ownerID == gerritbotGerritID
	minHumans := 1
	if isPR {
		minHumans = 2
	}
	reject := []string{gobotGerritID, gerritbotGerritID, kokoroGerritID, goLUCIGerritID, triciumGerritID, ownerID}
	ownerOrRobot := func(gerritID string) bool {
		for _, r := range reject {
			if gerritID == r {
				return true
			}
		}
		return false
	}

	ids := slices.DeleteFunc(reviewersInMetas(cl.Metas), ownerOrRobot)
	if len(ids) >= minHumans {
		return ids, true
	}

	reviewers, err := b.gerrit.ListReviewers(ctx, change.ID())
	if err != nil {
		if httpErr, ok := err.(*gerrit.HTTPError); ok && httpErr.Res.StatusCode == http.StatusNotFound {
			b.deletedChanges[change] = true
		}
		log.Printf("Could not list reviewers on change %q: %v", change.ID(), err)
		return nil, true
	}
	ids = []string{}
	for _, r := range reviewers {
		id := strconv.FormatInt(r.NumericID, 10)
		if hasServiceUserTag(r.AccountInfo) || ownerOrRobot(id) {
			// Skip bots and owner.
			continue
		}
		ids = append(ids, id)
	}
	return ids, len(ids) >= minHumans
}

// hasServiceUserTag reports whether the account has a SERVICE_USER tag.
func hasServiceUserTag(a gerrit.AccountInfo) bool {
	for _, t := range a.Tags {
		if t == "SERVICE_USER" {
			return true
		}
	}
	return false
}

// autoSubmitCLs submits CLs which are labelled "Auto-Submit",
// have all submit requirements satisfied according to Gerrit, and
// aren't waiting for a parent CL in the stack to be handled.
//
// See go.dev/issue/48021.
func (b *gopherbot) autoSubmitCLs(ctx context.Context) error {
	return b.corpus.Gerrit().ForeachProjectUnsorted(func(gp *maintner.GerritProject) error {
		if gp.Server() != "go.googlesource.com" {
			return nil
		}
		return gp.ForeachOpenCL(func(cl *maintner.GerritCL) error {
			gc := gerritChange{gp.Project(), cl.Number}
			if b.deletedChanges[gc] {
				return nil
			}

			// Break out early (before making Gerrit API calls) if the Auto-Submit label
			// hasn't been used at all in this CL.
			var autosubmitPresent bool
			for _, meta := range cl.Metas {
				if strings.Contains(meta.Commit.Msg, "\nLabel: Auto-Submit") {
					autosubmitPresent = true
					break
				}
			}
			if !autosubmitPresent {
				return nil
			}

			// Skip this CL if Auto-Submit+1 isn't actively set on it.
			changeInfo, err := b.gerrit.GetChange(ctx, fmt.Sprint(cl.Number), gerrit.QueryChangesOpt{Fields: []string{"LABELS", "SUBMITTABLE"}})
			if err != nil {
				if httpErr, ok := err.(*gerrit.HTTPError); ok && httpErr.Res.StatusCode == http.StatusNotFound {
					b.deletedChanges[gc] = true
				}
				log.Printf("Could not retrieve change %q: %v", gc.ID(), err)
				return nil
			}
			if autosubmitActive := changeInfo.Labels["Auto-Submit"].Approved != nil; !autosubmitActive {
				return nil
			}
			// NOTE: we might be able to skip this as well, since the revision action
			// check will also cover this...
			if !changeInfo.Submittable {
				return nil
			}

			// We need to check the mergeability, as well as the submitability,
			// as the latter doesn't take into account merge conflicts, just
			// if the change satisfies the project submit rules.
			//
			// NOTE: this may now be redundant, since the revision action check
			// below will also inherently checks mergeability, since the change
			// cannot actually be submitted if there is a merge conflict. We
			// may be able to just skip this entirely.
			mi, err := b.gerrit.GetMergeable(ctx, fmt.Sprint(cl.Number), "current")
			if err != nil {
				return err
			}
			if !mi.Mergeable || mi.CommitMerged {
				return nil
			}

			ra, err := b.gerrit.GetRevisionActions(ctx, fmt.Sprint(cl.Number), "current")
			if err != nil {
				return err
			}
			if ra["submit"] == nil || !ra["submit"].Enabled {
				return nil
			}

			// If this change is part of a stack, we'd like to merge the stack
			// in the correct order (i.e. from the bottom of the stack to the
			// top), so we'll only merge the current change if every change
			// below it in the stack is either merged, or abandoned.
			// GetRelatedChanges gives us the stack from top to bottom (the
			// order of the git commits, from newest to oldest, see Gerrit
			// documentation for RelatedChangesInfo), so first we find our
			// change in the stack, then  check everything below it.
			relatedChanges, err := b.gerrit.GetRelatedChanges(ctx, fmt.Sprint(cl.Number), "current")
			if err != nil {
				return err
			}
			if len(relatedChanges.Changes) > 0 {
				var parentChanges bool
				for _, ci := range relatedChanges.Changes {
					if !parentChanges {
						// Skip everything before the change we are checking, as
						// they are the children of this change, and we only care
						// about the parents.
						parentChanges = ci.ChangeNumber == cl.Number
						continue
					}
					if ci.Status != gerrit.ChangeStatusAbandoned &&
						ci.Status != gerrit.ChangeStatusMerged {
						return nil
					}
					// We do not check the revision number of merged/abandoned
					// parents since, even if they are not current according to
					// gerrit, if there were any merge conflicts, caused by the
					// diffs between the revision this change was based on and
					// the current revision, the change would not be considered
					// submittable anyway.
				}
			}

			if *dryRun {
				log.Printf("[dry-run] would've submitted CL https://golang.org/cl/%d ...", cl.Number)
				return nil
			}
			log.Printf("submitting CL https://golang.org/cl/%d ...", cl.Number)

			// TODO: if maintner isn't fast enough (or is too fast) and it re-runs this
			// before the submission is noticed, we may run this more than once. This
			// could be handled with a local cache of "recently submitted" changes to
			// be ignored.
			_, err = b.gerrit.SubmitChange(ctx, fmt.Sprint(cl.Number))
			return err
		})
	})
}

type issueFlags uint8

const (
	open        issueFlags = 1 << iota // Include open issues.
	closed                             // Include closed issues.
	includePRs                         // Include issues that are Pull Requests.
	includeGone                        // Include issues that are gone (e.g., deleted or transferred).
)

// foreachIssue calls fn for each issue in repo gr as controlled by flags.
//
// If fn returns an error, iteration ends and foreachIssue returns
// with that error.
//
// The fn function is called serially, with increasingly numbered
// issues.
func (b *gopherbot) foreachIssue(gr *maintner.GitHubRepo, flags issueFlags, fn func(*maintner.GitHubIssue) error) error {
	return gr.ForeachIssue(func(gi *maintner.GitHubIssue) error {
		switch {
		case (flags&open == 0) && !gi.Closed,
			(flags&closed == 0) && gi.Closed,
			(flags&includePRs == 0) && gi.PullRequest,
			(flags&includeGone == 0) && (gi.NotExist || b.deletedIssues[githubIssue{gr.ID(), gi.Number}]):
			// Skip issue.
			return nil
		default:
			return fn(gi)
		}
	})
}

// reviewerRe extracts the reviewer's Gerrit ID from a line that looks like:
//
//	Reviewer: Rebecca Stambler <16140@62eb7196-b449-3ce5-99f1-c037f21e1705>
var reviewerRe = regexp.MustCompile(`.* <(?P<id>\d+)@.*>`)

const gerritInstanceID = "@62eb7196-b449-3ce5-99f1-c037f21e1705"

// reviewersInMetas returns the unique Gerrit IDs of reviewers
// (in REVIEWER and CC states) that were at some point added
// to the given Gerrit CL, even if they've been since removed.
func reviewersInMetas(metas []*maintner.GerritMeta) []string {
	var ids []string
	for _, m := range metas {
		if !strings.Contains(m.Commit.Msg, "Reviewer:") && !strings.Contains(m.Commit.Msg, "CC:") {
			continue
		}

		err := foreach.LineStr(m.Commit.Msg, func(ln string) error {
			if !strings.HasPrefix(ln, "Reviewer:") && !strings.HasPrefix(ln, "CC:") {
				return nil
			}
			match := reviewerRe.FindStringSubmatch(ln)
			if match == nil {
				return nil
			}
			// Extract the reviewer's Gerrit ID.
			for i, name := range reviewerRe.SubexpNames() {
				if name != "id" {
					continue
				}
				if i < 0 || i > len(match) {
					continue
				}
				ids = append(ids, match[i])
			}
			return nil
		})
		if err != nil {
			log.Printf("reviewersInMetas: got unexpected error from foreach.LineStr: %v", err)
		}
	}
	// Remove duplicates.
	slices.Sort(ids)
	ids = slices.Compact(ids)
	return ids
}

func getCodeOwners(ctx context.Context, paths []string) ([]*owners.Entry, error) {
	oReq := owners.Request{Version: 1}
	oReq.Payload.Paths = paths

	oResp, err := fetchCodeOwners(ctx, &oReq)
	if err != nil {
		return nil, err
	}

	var entries []*owners.Entry
	for _, entry := range oResp.Payload.Entries {
		if entry == nil {
			continue
		}
		entries = append(entries, entry)
	}
	return entries, nil
}

func getAllCodeOwners(ctx context.Context) (map[string]*owners.Entry, error) {
	oReq := owners.Request{Version: 1}
	oReq.Payload.All = true
	oResp, err := fetchCodeOwners(ctx, &oReq)
	if err != nil {
		return nil, err
	}
	return oResp.Payload.Entries, nil
}

func fetchCodeOwners(ctx context.Context, oReq *owners.Request) (*owners.Response, error) {
	b, err := json.Marshal(oReq)
	if err != nil {
		return nil, err
	}
	req, err := http.NewRequest("POST", "https://dev.golang.org/owners/", bytes.NewReader(b))
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", "application/json")
	ctx, cancel := context.WithTimeout(ctx, 10*time.Second)
	defer cancel()
	resp, err := http.DefaultClient.Do(req.WithContext(ctx))
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	var oResp owners.Response
	if err := json.NewDecoder(resp.Body).Decode(&oResp); err != nil {
		return nil, fmt.Errorf("could not decode owners response: %v", err)
	}
	if oResp.Error != "" {
		return nil, fmt.Errorf("error from dev.golang.org/owners endpoint: %v", oResp.Error)
	}
	return &oResp, nil
}

// mergeOwnersEntries takes multiple owners.Entry structs and aggregates all
// primary and secondary users into a single entry.
// If a user is a primary in one entry but secondary on another, they are
// primary in the returned entry.
// If a users email matches the authorEmail, the user is omitted from the
// result.
// The resulting order of the entries is non-deterministic.
func mergeOwnersEntries(entries []*owners.Entry, authorEmail string) *owners.Entry {
	var result owners.Entry
	pm := make(map[owners.Owner]int)
	for _, e := range entries {
		for _, o := range e.Primary {
			pm[o]++
		}
	}
	sm := make(map[owners.Owner]int)
	for _, e := range entries {
		for _, o := range e.Secondary {
			if pm[o] > 0 {
				pm[o]++
			} else {
				sm[o]++
			}
		}
	}

	const maxReviewers = 3
	if len(pm) > maxReviewers {
		// Spamming many reviewers.
		// Cut to three most common reviewers
		// and drop all the secondaries.
		var keep []owners.Owner
		for o := range pm {
			keep = append(keep, o)
		}
		sort.Slice(keep, func(i, j int) bool {
			return pm[keep[i]] > pm[keep[j]]
		})
		keep = keep[:maxReviewers]
		sort.Slice(keep, func(i, j int) bool {
			return keep[i].GerritEmail < keep[j].GerritEmail
		})
		return &owners.Entry{Primary: keep}
	}

	for o := range pm {
		if o.GerritEmail != authorEmail {
			result.Primary = append(result.Primary, o)
		}
	}
	for o := range sm {
		if o.GerritEmail != authorEmail {
			result.Secondary = append(result.Secondary, o)
		}
	}
	return &result
}

// filterGerritOwners removes all primary and secondary owners from entries
// that are missing GerritEmail, and thus cannot be Gerrit reviewers (e.g.,
// GitHub Teams).
//
// If an Entry's primary reviewers is empty after this process, the secondary
// owners are upgraded to primary.
func filterGerritOwners(entries []*owners.Entry) []*owners.Entry {
	result := make([]*owners.Entry, 0, len(entries))
	for _, e := range entries {
		var clean owners.Entry
		for _, owner := range e.Primary {
			if owner.GerritEmail != "" {
				clean.Primary = append(clean.Primary, owner)
			}
		}
		for _, owner := range e.Secondary {
			if owner.GerritEmail != "" {
				clean.Secondary = append(clean.Secondary, owner)
			}
		}
		if len(clean.Primary) == 0 {
			clean.Primary = clean.Secondary
			clean.Secondary = nil
		}
		result = append(result, &clean)
	}
	return result
}

func blockqoute(s string) string {
	s = strings.TrimSpace(s)
	s = "> " + s
	s = strings.Replace(s, "\n", "\n> ", -1)
	return s
}

// errStopIteration is used to stop iteration over issues or comments.
// It has no special meaning.
var errStopIteration = errors.New("stop iteration")

func isDocumentationTitle(t string) bool {
	if !strings.Contains(t, "doc") && !strings.Contains(t, "Doc") {
		return false
	}
	t = strings.ToLower(t)
	if strings.HasPrefix(t, "x/pkgsite:") {
		// Don't label pkgsite issues with the Documentation label.
		return false
	}
	if strings.HasPrefix(t, "doc:") {
		return true
	}
	if strings.HasPrefix(t, "docs:") {
		return true
	}
	if strings.HasPrefix(t, "cmd/doc:") {
		return false
	}
	if strings.HasPrefix(t, "go/doc:") {
		return false
	}
	if strings.Contains(t, "godoc:") { // in x/tools, or the dozen places people file it as
		return false
	}
	return strings.Contains(t, "document") ||
		strings.Contains(t, "docs ")
}

func isGoplsTitle(t string) bool {
	// If the prefix doesn't contain "gopls" or "lsp",
	// then it may not be a gopls issue.
	i := strings.Index(t, ":")
	if i > -1 {
		t = t[:i]
	}
	return strings.Contains(t, "gopls") || strings.Contains(t, "lsp")
}

var lastTask string

func printIssue(task string, repoID maintner.GitHubRepoID, gi *maintner.GitHubIssue) {
	if *dryRun {
		task = task + " [dry-run]"
	}
	if task != lastTask {
		fmt.Println(task)
		lastTask = task
	}
	if repoID.Owner != "golang" || repoID.Repo != "go" {
		fmt.Printf("\thttps://github.com/%s/issues/%v  %s\n", repoID, gi.Number, gi.Title)
	} else {
		fmt.Printf("\thttps://go.dev/issue/%v  %s\n", gi.Number, gi.Title)
	}
}

func repoHasLabel(repo *maintner.GitHubRepo, name string) bool {
	has := false
	repo.ForeachLabel(func(label *maintner.GitHubLabel) error {
		if label.Name == name {
			has = true
		}
		return nil
	})
	return has
}
