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

// Logic to interact with a Gerrit server. Gerrit has an entire Git-based
// protocol for fetching metadata about CL's, reviewers, patch comments, which
// is used here - we don't use the x/build/gerrit client, which hits the API.
// TODO: write about Gerrit's Git API.

package maintner

import (
	"bufio"
	"bytes"
	"context"
	"errors"
	"fmt"
	"log"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"sort"
	"strconv"
	"strings"
	"time"

	"golang.org/x/build/internal/envutil"
	"golang.org/x/build/maintner/maintpb"
)

// Gerrit holds information about a number of Gerrit projects.
type Gerrit struct {
	c        *Corpus
	projects map[string]*GerritProject // keyed by "go.googlesource.com/build"

	clsReferencingGithubIssue map[GitHubIssueRef][]*GerritCL
}

func normalizeGerritServer(server string) string {
	u, err := url.Parse(server)
	if err == nil && u.Host != "" {
		server = u.Host
	}
	if strings.HasSuffix(server, "-review.googlesource.com") {
		// special case: the review site is hosted at a different URL than the
		// Git checkout URL.
		return strings.Replace(server, "-review.googlesource.com", ".googlesource.com", 1)
	}
	return server
}

// Project returns the specified Gerrit project if it's known, otherwise
// it returns nil. Server is the Gerrit server's hostname, such as
// "go.googlesource.com".
func (g *Gerrit) Project(server, project string) *GerritProject {
	server = normalizeGerritServer(server)
	return g.projects[server+"/"+project]
}

// c.mu must be held
func (g *Gerrit) getOrCreateProject(gerritProj string) *GerritProject {
	proj, ok := g.projects[gerritProj]
	if ok {
		return proj
	}
	proj = &GerritProject{
		gerrit: g,
		proj:   gerritProj,
		cls:    map[int32]*GerritCL{},
		remote: map[gerritCLVersion]GitHash{},
		ref:    map[string]GitHash{},
		commit: map[GitHash]*GitCommit{},
		need:   map[GitHash]bool{},
	}
	g.projects[gerritProj] = proj
	return proj
}

// ForeachProjectUnsorted calls fn for each known Gerrit project.
// Iteration ends if fn returns a non-nil value.
func (g *Gerrit) ForeachProjectUnsorted(fn func(*GerritProject) error) error {
	for _, p := range g.projects {
		if err := fn(p); err != nil {
			return err
		}
	}
	return nil
}

// GerritProject represents a single Gerrit project.
type GerritProject struct {
	gerrit          *Gerrit
	proj            string // "go.googlesource.com/net"
	cls             map[int32]*GerritCL
	remote          map[gerritCLVersion]GitHash
	need            map[GitHash]bool
	commit          map[GitHash]*GitCommit
	numLabelChanges int // incremented (too many times) by meta commits with "Label:" updates
	dirtyCL         map[*GerritCL]struct{}

	// ref are the non-change refs with keys like "HEAD",
	// "refs/heads/master", "refs/tags/v0.8.0", etc.
	//
	// Notably, this excludes the "refs/changes/*" refs matched by
	// rxChangeRef. Those are in the remote map.
	ref map[string]GitHash
}

// Ref returns a non-change ref, such as "HEAD", "refs/heads/master",
// or "refs/tags/v0.8.0",
// Change refs of the form "refs/changes/*" are not supported.
// The returned hash is the zero value (an empty string) if the ref
// does not exist.
func (gp *GerritProject) Ref(ref string) GitHash {
	return gp.ref[ref]
}

func (gp *GerritProject) gitDir() string {
	return filepath.Join(gp.gerrit.c.getDataDir(), url.PathEscape(gp.proj))
}

// NumLabelChanges is an inaccurate count the number of times vote labels have
// changed in this project. This number is monotonically increasing.
// This is not guaranteed to be accurate; it definitely overcounts, but it
// at least increments when changes are made.
// It will not undercount.
func (gp *GerritProject) NumLabelChanges() int {
	// TODO: rename this method.
	return gp.numLabelChanges
}

// ServerSlashProject returns the server and project together, such as
// "go.googlesource.com/build".
func (gp *GerritProject) ServerSlashProject() string { return gp.proj }

// Server returns the Gerrit server, such as "go.googlesource.com".
func (gp *GerritProject) Server() string {
	if i := strings.IndexByte(gp.proj, '/'); i != -1 {
		return gp.proj[:i]
	}
	return ""
}

// Project returns the Gerrit project on the server, such as "go" or "crypto".
func (gp *GerritProject) Project() string {
	if i := strings.IndexByte(gp.proj, '/'); i != -1 {
		return gp.proj[i+1:]
	}
	return ""
}

// ForeachNonChangeRef calls fn for each git ref on the server that is
// not a change (code review) ref. In general, these correspond to
// submitted changes.
// fn is called serially with sorted ref names.
// Iteration stops with the first non-nil error returned by fn.
func (gp *GerritProject) ForeachNonChangeRef(fn func(ref string, hash GitHash) error) error {
	refs := make([]string, 0, len(gp.ref))
	for ref := range gp.ref {
		refs = append(refs, ref)
	}
	sort.Strings(refs)
	for _, ref := range refs {
		if err := fn(ref, gp.ref[ref]); err != nil {
			return err
		}
	}
	return nil
}

// ForeachOpenCL calls fn for each open CL in the repo.
//
// If fn returns an error, iteration ends and ForeachOpenCL returns
// with that error.
//
// The fn function is called serially, with increasingly numbered
// CLs.
func (gp *GerritProject) ForeachOpenCL(fn func(*GerritCL) error) error {
	var s []*GerritCL
	for _, cl := range gp.cls {
		if !cl.complete() || cl.Status != "new" || cl.Private {
			continue
		}
		s = append(s, cl)
	}
	sort.Slice(s, func(i, j int) bool { return s[i].Number < s[j].Number })
	for _, cl := range s {
		if err := fn(cl); err != nil {
			return err
		}
	}
	return nil
}

// ForeachCLUnsorted calls fn for each CL in the repo, in any order.
//
// If fn returns an error, iteration ends and ForeachCLUnsorted returns with
// that error.
func (gp *GerritProject) ForeachCLUnsorted(fn func(*GerritCL) error) error {
	for _, cl := range gp.cls {
		if !cl.complete() {
			continue
		}
		if err := fn(cl); err != nil {
			return err
		}
	}
	return nil
}

// CL returns the GerritCL with the given number, or nil if it is not present.
//
// CL numbers are shared across all projects on a Gerrit server, so you can get
// nil unless you have the GerritProject containing that CL.
func (gp *GerritProject) CL(number int32) *GerritCL {
	if cl := gp.cls[number]; cl != nil && cl.complete() {
		return cl
	}
	return nil
}

// GitCommit returns the provided git commit, or nil if it's unknown.
func (gp *GerritProject) GitCommit(hash string) *GitCommit {
	if len(hash) != 40 {
		// TODO: support prefix lookups. build a trie. But
		// for now just avoid panicking in gitHashFromHexStr.
		return nil
	}
	var buf [20]byte
	_, err := decodeHexStr(buf[:], hash)
	if err != nil {
		return nil
	}
	return gp.commit[GitHash(buf[:])]
}

func (gp *GerritProject) logf(format string, args ...interface{}) {
	log.Printf("gerrit "+gp.proj+": "+format, args...)
}

// gerritCLVersion is a value type used as a map key to store a CL
// number and a patchset version. Its Version field is overloaded
// to reference the "meta" metadata commit if the Version is 0.
type gerritCLVersion struct {
	CLNumber int32
	Version  int32 // version 0 is used for the "meta" ref.
}

// A GerritCL represents a single change in Gerrit.
type GerritCL struct {
	// Project is the project this CL is part of.
	Project *GerritProject

	// Number is the CL number on the Gerrit server (e.g. 1, 2, 3). 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).
	Number int32

	// Created is the CL creation time.
	Created time.Time

	// Version is the number of versions of the patchset for this
	// CL seen so far. It starts at 1.
	Version int32

	// Commit is the git commit of the latest version of this CL.
	// Previous versions are available via CommitAtVersion.
	// Commit is always non-nil.
	Commit *GitCommit

	// branch is a cache of the latest "Branch: " value seen from
	// MetaCommits' commit message values, stripped of any
	// "refs/heads/" prefix. It's usually "master".
	branch string

	// Meta is the head of the most recent Gerrit "meta" commit
	// for this CL. This is guaranteed to be a linear history
	// back to a CL-specific root commit for this meta branch.
	// Meta will always be non-nil.
	Meta *GerritMeta

	// Metas contains the history of Meta commits, from the oldest (root)
	// to the most recent. The last item in the slice is the same
	// value as the GerritCL.Meta field.
	// The Metas slice will always contain at least 1 element.
	Metas []*GerritMeta

	// Status will be "merged", "abandoned", "new", or "draft".
	Status string

	// Private indicates whether this is a private CL.
	// Empirically, it seems that one meta commit of private CLs is
	// sometimes visible to everybody, even when the rest of the details
	// and later meta commits are not. In general, if you see this
	// being set to true, treat this CL as if it doesn't exist.
	Private bool

	// GitHubIssueRefs are parsed references to GitHub issues.
	// Multiple references to the same issue are deduplicated.
	GitHubIssueRefs []GitHubIssueRef

	// Messages contains all of the messages for this CL, in sorted order.
	Messages []*GerritMessage
}

// complete reports whether cl is complete.
// A CL is considered complete if its Meta and Commit fields are non-nil,
// and the Metas slice contains at least 1 element.
func (cl *GerritCL) complete() bool {
	return cl.Meta != nil &&
		len(cl.Metas) >= 1 &&
		cl.Commit != nil
}

// GerritMessage is a Gerrit reply that is attached to the CL as a whole, and
// not to a file or line of a patch set.
//
// Maintner does very little parsing or formatting of a Message body. Messages
// are stored the same way they are stored in the API.
type GerritMessage struct {
	// Meta is the commit containing the message.
	Meta *GitCommit

	// Version is the patch set version this message was sent on.
	Version int32

	// Message is the raw message contents from Gerrit (a subset
	// of the raw git commit message), starting with "Patch Set
	// nnnn".
	Message string

	// Date is when this message was stored (the commit time of
	// the git commit).
	Date time.Time

	// Author returns the author of the commit. This takes the form "Gerrit User
	// 13437 <13437@62eb7196-b449-3ce5-99f1-c037f21e1705>", where the number
	// before the '@' sign is your Gerrit user ID, and the UUID after the '@' sign
	// seems to be the same for all commits for the same Gerrit server, across
	// projects.
	//
	// TODO: Merge the *GitPerson object here and for a person's Git commits
	// (which use their real email) via the user ID, so they point to the same
	// object.
	Author *GitPerson
}

// References reports whether cl includes a commit message reference
// to the provided Github issue ref.
func (cl *GerritCL) References(ref GitHubIssueRef) bool {
	for _, eref := range cl.GitHubIssueRefs {
		if eref == ref {
			return true
		}
	}
	return false
}

// Branch returns the CL's branch, with any "refs/heads/" prefix removed.
func (cl *GerritCL) Branch() string { return cl.branch }

func (cl *GerritCL) updateBranch() {
	for i := len(cl.Metas) - 1; i >= 0; i-- {
		mc := cl.Metas[i]
		branch := lineValue(mc.Commit.Msg, "Branch:")
		if branch != "" {
			cl.branch = strings.TrimPrefix(branch, "refs/heads/")
			return
		}
	}
}

// lineValueOK extracts a value from an RFC 822-style "key: value" series of lines.
// If all is,
//
//	foo: bar
//	bar: baz
//
// lineValue(all, "foo:") returns "bar". It trims any whitespace.
// The prefix is case sensitive and must include the colon.
// The ok value reports whether a line with such a prefix is found, even if its
// value is empty. If ok is true, the rest value contains the subsequent lines.
func lineValueOK(all, prefix string) (value, rest string, ok bool) {
	orig := all
	consumed := 0
	for {
		i := strings.Index(all, prefix)
		if i == -1 {
			return "", "", false
		}
		if i > 0 && all[i-1] != '\n' && all[i-1] != '\r' {
			all = all[i+len(prefix):]
			consumed += i + len(prefix)
			continue
		}
		val := all[i+len(prefix):]
		consumed += i + len(prefix)
		if nl := strings.IndexByte(val, '\n'); nl != -1 {
			consumed += nl + 1
			val = val[:nl+1]
		} else {
			consumed = len(orig)
		}
		return strings.TrimSpace(val), orig[consumed:], true
	}
}

func lineValue(all, prefix string) string {
	value, _, _ := lineValueOK(all, prefix)
	return value
}

func lineValueRest(all, prefix string) (value, rest string) {
	value, rest, _ = lineValueOK(all, prefix)
	return
}

// WorkInProgress reports whether the CL has its Work-in-progress bit set, per
// https://gerrit-review.googlesource.com/Documentation/intro-user.html#wip
func (cl *GerritCL) WorkInProgress() bool {
	var wip bool
	for _, m := range cl.Metas {
		switch lineValue(m.Commit.Msg, "Work-in-progress:") {
		case "true":
			wip = true
		case "false":
			wip = false
		}
	}
	return wip
}

// ChangeID returns the Gerrit "Change-Id: Ixxxx" line's Ixxxx
// value from the cl.Msg, if any.
func (cl *GerritCL) ChangeID() string {
	id := cl.Footer("Change-Id:")
	if strings.HasPrefix(id, "I") && len(id) == 41 {
		return id
	}
	return ""
}

// Footer returns the value of a line of the form <key>: value from
// the CL’s commit message. The key is case-sensitive and must end in
// a colon.
// An empty string is returned if there is no value for key.
func (cl *GerritCL) Footer(key string) string {
	if len(key) == 0 || key[len(key)-1] != ':' {
		panic("Footer key does not end in colon")
	}
	// TODO: git footers are treated as multimaps. Account for this.
	return lineValue(cl.Commit.Msg, key)
}

// OwnerID returns the ID of the CL’s owner. It will return -1 on error.
func (cl *GerritCL) OwnerID() int {
	if !cl.complete() {
		return -1
	}
	// Meta commits caused by the owner of a change have an email of the form
	// <user id>@<uuid of gerrit server>.
	email := cl.Metas[0].Commit.Author.Email()
	idx := strings.Index(email, "@")
	if idx == -1 {
		return -1
	}
	id, err := strconv.Atoi(email[:idx])
	if err != nil {
		return -1
	}
	return id
}

// Owner returns the author of the first commit to the CL. It returns nil on error.
func (cl *GerritCL) Owner() *GitPerson {
	// The owner of a change is a numeric ID that can have more than one email
	// associated with it, but the email associated with the very first upload is
	// designated as the owner of the change by Gerrit.
	hash, ok := cl.Project.remote[gerritCLVersion{CLNumber: cl.Number, Version: 1}]
	if !ok {
		return nil
	}
	commit, ok := cl.Project.commit[hash]
	if !ok {
		return nil
	}
	return commit.Author
}

// Subject returns the subject of the latest commit message.
// The subject is separated from the body by a blank line.
func (cl *GerritCL) Subject() string {
	if i := strings.Index(cl.Commit.Msg, "\n\n"); i >= 0 {
		return strings.Replace(cl.Commit.Msg[:i], "\n", " ", -1)
	}
	return strings.Replace(cl.Commit.Msg, "\n", " ", -1)
}

// CommitAtVersion returns the git commit of the specifid version of this CL.
// It returns nil if version is not in the range [1, cl.Version].
func (cl *GerritCL) CommitAtVersion(version int32) *GitCommit {
	if version < 1 || version > cl.Version {
		return nil
	}
	hash, ok := cl.Project.remote[gerritCLVersion{CLNumber: cl.Number, Version: version}]
	if !ok {
		return nil
	}
	return cl.Project.commit[hash]
}

func (cl *GerritCL) updateGithubIssueRefs() {
	gp := cl.Project
	gerrit := gp.gerrit
	gc := cl.Commit

	oldRefs := cl.GitHubIssueRefs
	newRefs := gerrit.c.parseGithubRefs(gp.proj, gc.Msg)
	cl.GitHubIssueRefs = newRefs
	for _, ref := range newRefs {
		if !clSliceContains(gerrit.clsReferencingGithubIssue[ref], cl) {
			// TODO: make this as small as
			// possible? Most will have length
			// 1. Care about default capacity of
			// 2?
			gerrit.clsReferencingGithubIssue[ref] = append(gerrit.clsReferencingGithubIssue[ref], cl)
		}
	}
	for _, ref := range oldRefs {
		if !cl.References(ref) {
			// TODO: remove ref from gerrit.clsReferencingGithubIssue
			// It could be a map of maps I suppose, but not as compact.
			// So uses a slice as the second layer, since there will normally
			// be one item.
		}
	}
}

// c.mu must be held
func (c *Corpus) initGerrit() {
	if c.gerrit != nil {
		return
	}
	c.gerrit = &Gerrit{
		c:                         c,
		projects:                  map[string]*GerritProject{},
		clsReferencingGithubIssue: map[GitHubIssueRef][]*GerritCL{},
	}
}

type watchedGerritRepo struct {
	project *GerritProject
}

// TrackGerrit registers the Gerrit project with the given project as a project
// to watch and append to the mutation log. Only valid in leader mode.
// The provided string should be of the form "hostname/project", without a scheme
// or trailing slash.
func (c *Corpus) TrackGerrit(gerritProj string) {
	if c.mutationLogger == nil {
		panic("can't TrackGerrit in non-leader mode")
	}
	c.mu.Lock()
	defer c.mu.Unlock()

	if strings.Count(gerritProj, "/") != 1 {
		panic(fmt.Sprintf("gerrit project argument %q expected to contain exactly 1 slash", gerritProj))
	}
	c.initGerrit()
	if _, dup := c.gerrit.projects[gerritProj]; dup {
		panic("duplicated watched gerrit project " + gerritProj)
	}
	project := c.gerrit.getOrCreateProject(gerritProj)
	if project == nil {
		panic("gerrit project not created")
	}
	c.watchedGerritRepos = append(c.watchedGerritRepos, watchedGerritRepo{
		project: project,
	})
}

// called with c.mu Locked
func (c *Corpus) processGerritMutation(gm *maintpb.GerritMutation) {
	if c.gerrit == nil {
		// TODO: option to ignore mutation if user isn't interested.
		c.initGerrit()
	}
	gp, ok := c.gerrit.projects[gm.Project]
	if !ok {
		// TODO: option to ignore mutation if user isn't interested.
		// For now, always process the record.
		gp = c.gerrit.getOrCreateProject(gm.Project)
	}
	gp.processMutation(gm)
}

var statusIndicator = "\nStatus: "

// The Go Gerrit site does not really use the "draft" status much, but if
// you need to test it, create a dummy commit and then run
//
//	git push origin HEAD:refs/drafts/master
var statuses = []string{"merged", "abandoned", "draft", "new"}

// getGerritStatus returns a Gerrit status for a commit, or the empty string to
// indicate the commit did not show a status.
//
// getGerritStatus relies on the Gerrit code review convention of amending
// the meta commit to include the current status of the CL. The Gerrit search
// bar allows you to search for changes with the following statuses: "open",
// "reviewed", "closed", "abandoned", "merged", "draft", "pending". The REST API
// returns only "NEW", "DRAFT", "ABANDONED", "MERGED". Gerrit attaches "draft",
// "abandoned", "new", and "merged" statuses to some meta commits; you may have
// to search the current meta commit's parents to find the last good commit.
func getGerritStatus(commit *GitCommit) string {
	idx := strings.Index(commit.Msg, statusIndicator)
	if idx == -1 {
		return ""
	}
	off := idx + len(statusIndicator)
	for _, status := range statuses {
		if strings.HasPrefix(commit.Msg[off:], status) {
			return status
		}
	}
	return ""
}

var errTooManyParents = errors.New("maintner: too many commit parents")

// foreachCommit walks an entire linear git history, starting at commit itself,
// and iterating over all of its parents. commit must be non-nil.
// f is called for each commit until an error is returned from f, or a commit has no parent.
//
// foreachCommit returns errTooManyParents (and stops processing) if a commit
// has more than one parent.
// An error is returned if a commit has a parent that cannot be found.
//
// Corpus.mu must be held.
func (gp *GerritProject) foreachCommit(commit *GitCommit, f func(*GitCommit) error) error {
	c := gp.gerrit.c
	for {
		if err := f(commit); err != nil {
			return err
		}
		if len(commit.Parents) == 0 {
			// No parents, we're at the end of the linear history.
			return nil
		}
		if len(commit.Parents) > 1 {
			return errTooManyParents
		}
		parentHash := commit.Parents[0].Hash // meta tree has no merge commits
		commit = c.gitCommit[parentHash]
		if commit == nil {
			return fmt.Errorf("parent commit %v not found", parentHash)
		}
	}
}

// getGerritMessage parses a Gerrit comment from the given commit or returns nil
// if there wasn't one.
//
// Corpus.mu must be held.
func (gp *GerritProject) getGerritMessage(commit *GitCommit) *GerritMessage {
	const existVerPhrase = "\nPatch Set "
	const newVerPhrase = "\nUploaded patch set "

	startExist := strings.Index(commit.Msg, existVerPhrase)
	startNew := strings.Index(commit.Msg, newVerPhrase)
	var start int
	var phrase string
	switch {
	case startExist == -1 && startNew == -1:
		return nil
	case startExist == -1 || (startNew != -1 && startNew < startExist):
		phrase = newVerPhrase
		start = startNew
	case startNew == -1 || (startExist != -1 && startExist < startNew):
		phrase = existVerPhrase
		start = startExist
	}

	numStart := start + len(phrase)
	colon := strings.IndexByte(commit.Msg[numStart:], ':')
	if colon == -1 {
		return nil
	}
	num := commit.Msg[numStart : numStart+colon]
	if strings.Contains(num, "\n") || strings.Contains(num, ".") {
		// Spanned lines. Didn't match expected comment form
		// we care about (comments with vote changes), like:
		//
		//    Uploaded patch set 5: Some-Vote=+2
		//
		// For now, treat such meta updates (new uploads only)
		// as not comments.
		return nil
	}
	version, err := strconv.ParseInt(num, 10, 32)
	if err != nil {
		gp.logf("for phrase %q at %d, unexpected patch set number in %s; err: %v, message: %s", phrase, start, commit.Hash, err, commit.Msg)
		return nil
	}
	start++
	v := commit.Msg[start:]
	l := 0
	for {
		i := strings.IndexByte(v, '\n')
		if i < 0 {
			return nil
		}
		if strings.HasPrefix(v[:i], "Patch-set:") {
			// two newlines before the Patch-set message
			v = commit.Msg[start : start+l-2]
			break
		}
		v = v[i+1:]
		l = l + i + 1
	}
	return &GerritMessage{
		Meta:    commit,
		Author:  commit.Author,
		Date:    commit.CommitTime,
		Message: v,
		Version: int32(version),
	}
}

func reverseGerritMessages(ss []*GerritMessage) {
	for i := len(ss)/2 - 1; i >= 0; i-- {
		opp := len(ss) - 1 - i
		ss[i], ss[opp] = ss[opp], ss[i]
	}
}

func reverseGerritMetas(ss []*GerritMeta) {
	for i := len(ss)/2 - 1; i >= 0; i-- {
		opp := len(ss) - 1 - i
		ss[i], ss[opp] = ss[opp], ss[i]
	}
}

// called with c.mu Locked
func (gp *GerritProject) processMutation(gm *maintpb.GerritMutation) {
	c := gp.gerrit.c

	for _, commitp := range gm.Commits {
		gc, err := c.processGitCommit(commitp)
		if err != nil {
			gp.logf("error processing commit %q: %v", commitp.Sha1, err)
			continue
		}
		gp.commit[gc.Hash] = gc
		delete(gp.need, gc.Hash)

		for _, p := range gc.Parents {
			gp.markNeededCommit(p.Hash)
		}
	}

	for _, refName := range gm.DeletedRefs {
		delete(gp.ref, refName)
		// TODO: this doesn't delete change refs (from
		// gp.remote) yet, mostly because those don't tend to
		// ever get deleted and we haven't yet needed it. If
		// we ever need it, the mutation generation side would
		// also need to be updated.
	}

	for _, refp := range gm.Refs {
		refName := refp.Ref
		hash := c.gitHashFromHexStr(refp.Sha1)
		m := rxChangeRef.FindStringSubmatch(refName)
		if m == nil {
			if strings.HasPrefix(refName, "refs/meta/") {
				// Some of these slipped in to the data
				// before we started ignoring them. So ignore them here.
				continue
			}
			// Misc ref, not a change ref.
			if _, ok := c.gitCommit[hash]; !ok {
				gp.logf("ERROR: non-change ref %v references unknown hash %v; ignoring", refp, hash)
				continue
			}
			gp.ref[refName] = hash
			continue
		}

		clNum64, err := strconv.ParseInt(m[1], 10, 32)
		version, ok := gerritVersionNumber(m[2])
		if !ok || err != nil {
			continue
		}
		gc, ok := c.gitCommit[hash]
		if !ok {
			gp.logf("ERROR: ref %v references unknown hash %v; ignoring", refp, hash)
			continue
		}
		clv := gerritCLVersion{int32(clNum64), version}
		gp.remote[clv] = hash
		cl := gp.getOrCreateCL(clv.CLNumber)

		if clv.Version == 0 { // is a meta commit
			cl.Meta = newGerritMeta(gc, cl)
			gp.noteDirtyCL(cl) // needs processing at end of sync
		} else {
			cl.Commit = gc
			cl.Version = clv.Version
			cl.updateGithubIssueRefs()
		}
		if c.didInit {
			gp.logf("Ref %+v => %v", clv, hash)
		}
	}
}

// noteDirtyCL notes a CL that needs further processing before the corpus
// is returned to the user.
// cl.Meta must be non-nil.
//
// called with Corpus.mu Locked
func (gp *GerritProject) noteDirtyCL(cl *GerritCL) {
	if cl.Meta == nil {
		panic("noteDirtyCL given a GerritCL with a nil Meta field")
	}
	if gp.dirtyCL == nil {
		gp.dirtyCL = make(map[*GerritCL]struct{})
	}
	gp.dirtyCL[cl] = struct{}{}
}

// called with Corpus.mu Locked
func (gp *GerritProject) finishProcessing() {
	for cl := range gp.dirtyCL {
		// All dirty CLs have non-nil Meta, so it's safe to call finishProcessingCL.
		gp.finishProcessingCL(cl)
	}
	gp.dirtyCL = nil
}

// finishProcessingCL fixes up invariants before the cl can be returned back to the user.
// cl.Meta must be non-nil.
//
// called with Corpus.mu Locked
func (gp *GerritProject) finishProcessingCL(cl *GerritCL) {
	c := gp.gerrit.c

	mostRecentMetaCommit, ok := c.gitCommit[cl.Meta.Commit.Hash]
	if !ok {
		log.Printf("WARNING: GerritProject(%q).finishProcessingCL failed to find CL %v hash %s",
			gp.ServerSlashProject(), cl.Number, cl.Meta.Commit.Hash)
		return
	}

	foundStatus := ""

	// Walk from the newest meta commit backwards, so we store the messages
	// in reverse order and then flip the array before setting on the
	// GerritCL object.
	var backwardMessages []*GerritMessage
	var backwardMetas []*GerritMeta

	err := gp.foreachCommit(mostRecentMetaCommit, func(gc *GitCommit) error {
		if strings.Contains(gc.Msg, "\nLabel: ") {
			gp.numLabelChanges++
		}
		if strings.Contains(gc.Msg, "\nPrivate: true\n") {
			cl.Private = true
		}
		if gc.GerritMeta == nil {
			gc.GerritMeta = newGerritMeta(gc, cl)
		}
		if foundStatus == "" {
			foundStatus = getGerritStatus(gc)
		}
		backwardMetas = append(backwardMetas, gc.GerritMeta)
		if message := gp.getGerritMessage(gc); message != nil {
			backwardMessages = append(backwardMessages, message)
		}
		return nil
	})
	if err != nil {
		log.Printf("WARNING: GerritProject(%q).finishProcessingCL failed to walk CL %v meta history: %v",
			gp.ServerSlashProject(), cl.Number, err)
		return
	}

	if foundStatus != "" {
		cl.Status = foundStatus
	} else if cl.Status == "" {
		cl.Status = "new"
	}

	reverseGerritMessages(backwardMessages)
	cl.Messages = backwardMessages

	reverseGerritMetas(backwardMetas)
	cl.Metas = backwardMetas

	cl.Created = cl.Metas[0].Commit.CommitTime

	cl.updateBranch()
}

// clSliceContains reports whether cls contains cl.
func clSliceContains(cls []*GerritCL, cl *GerritCL) bool {
	for _, v := range cls {
		if v == cl {
			return true
		}
	}
	return false
}

// c.mu must be held
func (gp *GerritProject) markNeededCommit(hash GitHash) {
	if _, ok := gp.commit[hash]; ok {
		// Already have it.
		return
	}
	gp.need[hash] = true
}

// c.mu must be held
func (gp *GerritProject) getOrCreateCL(num int32) *GerritCL {
	cl, ok := gp.cls[num]
	if ok {
		return cl
	}
	cl = &GerritCL{
		Project: gp,
		Number:  num,
	}
	gp.cls[num] = cl
	return cl
}

func gerritVersionNumber(s string) (version int32, ok bool) {
	if s == "meta" {
		return 0, true
	}
	v, err := strconv.ParseInt(s, 10, 32)
	if err != nil {
		return 0, false
	}
	return int32(v), true
}

// rxRemoteRef matches "git ls-remote" lines.
//
// sample row:
// fd1e71f1594ce64941a85428ddef2fbb0ad1023e	refs/changes/99/30599/3
//
// Capture values:
//
//	$0: whole match
//	$1: "fd1e71f1594ce64941a85428ddef2fbb0ad1023e"
//	$2: "30599" (CL number)
//	$3: "1", "2" (patchset number) or "meta" (a/ special commit
//	    holding the comments for a commit)
//
// The "99" in the middle covers all CL's that end in "99", so
// refs/changes/99/99/1, refs/changes/99/199/meta.
var rxRemoteRef = regexp.MustCompile(`^([0-9a-f]{40,})\s+refs/changes/[0-9a-f]{2}/([0-9]+)/(.+)$`)

// $1: change num
// $2: version or "meta"
var rxChangeRef = regexp.MustCompile(`^refs/changes/[0-9a-f]{2}/([0-9]+)/(meta|(?:\d+))`)

func (gp *GerritProject) sync(ctx context.Context, loop bool) error {
	if err := gp.init(ctx); err != nil {
		gp.logf("init: %v", err)
		return err
	}
	activityCh := gp.gerrit.c.activityChan("gerrit:" + gp.proj)
	for {
		if err := gp.syncOnce(ctx); err != nil {
			if ee, ok := err.(*exec.ExitError); ok {
				err = fmt.Errorf("%v; stderr=%q", err, ee.Stderr)
			}
			gp.logf("sync: %v", err)
			return err
		}
		if !loop {
			return nil
		}
		timer := time.NewTimer(5 * time.Minute)
		select {
		case <-ctx.Done():
			timer.Stop()
			return ctx.Err()
		case <-activityCh:
			timer.Stop()
		case <-timer.C:
		}
	}
}

// syncMissingCommits is a cleanup step to fix a previous maintner bug where
// refs were updated without all their reachable commits being indexed and
// recorded in the log. This should only ever run once, and only in Go's history.
// If we restarted the log from the beginning this wouldn't be necessary.
func (gp *GerritProject) syncMissingCommits(ctx context.Context) error {
	c := gp.gerrit.c
	var hashes []GitHash
	c.mu.Lock()
	for hash := range gp.need {
		hashes = append(hashes, hash)
	}
	c.mu.Unlock()
	if len(hashes) == 0 {
		return nil
	}

	gp.logf("fixing indexing of %d missing commits", len(hashes))
	if err := gp.fetchHashes(ctx, hashes); err != nil {
		return err
	}

	n, err := gp.syncCommits(ctx)
	if err != nil {
		return err
	}
	gp.logf("%d missing commits indexed", n)
	return nil
}

func (gp *GerritProject) syncOnce(ctx context.Context) error {
	if err := gp.syncMissingCommits(ctx); err != nil {
		return err
	}

	c := gp.gerrit.c
	gitDir := gp.gitDir()

	t0 := time.Now()
	cmd := exec.CommandContext(ctx, "git", "fetch", "origin")
	envutil.SetDir(cmd, gitDir)
	// Enable extra Git tracing in case the fetch hangs.
	envutil.SetEnv(cmd,
		"GIT_TRACE2_EVENT=1",
		"GIT_TRACE_CURL_NO_DATA=1",
	)
	cmd.Stdout = new(bytes.Buffer)
	cmd.Stderr = cmd.Stdout

	// The 'git fetch' needs a timeout in case it hangs, but to avoid spurious
	// timeouts (and live-lock) the timeout should be (at least) an order of
	// magnitude longer than we expect the operation to actually take. Moreover,
	// exec.CommandContext sends SIGKILL, which may terminate the command without
	// giving it a chance to flush useful trace entries, so we'll terminate it
	// manually instead (see https://golang.org/issue/22757).
	if err := cmd.Start(); err != nil {
		return fmt.Errorf("git fetch origin: %v", err)
	}
	timer := time.AfterFunc(10*time.Minute, func() {
		cmd.Process.Signal(os.Interrupt)
	})
	err := cmd.Wait()
	fetchDuration := time.Since(t0).Round(time.Millisecond)
	timer.Stop()
	if err != nil {
		return fmt.Errorf("git fetch origin: %v after %v, %s", err, fetchDuration, cmd.Stdout)
	}
	gp.logf("ran git fetch origin in %v", fetchDuration)

	t0 = time.Now()
	cmd = exec.CommandContext(ctx, "git", "ls-remote")
	envutil.SetDir(cmd, gitDir)
	out, err := cmd.CombinedOutput()
	lsRemoteDuration := time.Since(t0).Round(time.Millisecond)
	if err != nil {
		return fmt.Errorf("git ls-remote in %s: %v after %v, %s", gitDir, err, lsRemoteDuration, out)
	}
	gp.logf("ran git ls-remote in %v", lsRemoteDuration)

	var changedRefs []*maintpb.GitRef
	var toFetch []GitHash

	bs := bufio.NewScanner(bytes.NewReader(out))

	// Take the lock here to access gp.remote and call c.gitHashFromHex.
	// It's acceptable to take such a coarse-looking lock because
	// it's not actually around I/O: all the input from ls-remote has
	// already been slurped into memory.
	c.mu.Lock()
	refExists := map[string]bool{} // whether ref is this ls-remote fetch
	for bs.Scan() {
		line := bs.Bytes()
		tab := bytes.IndexByte(line, '\t')
		if tab == -1 {
			if !strings.HasPrefix(bs.Text(), "From ") {
				gp.logf("bogus ls-remote line: %q", line)
			}
			continue
		}
		sha1 := string(line[:tab])
		refName := strings.TrimSpace(string(line[tab+1:]))
		refExists[refName] = true
		hash := c.gitHashFromHexStr(sha1)

		var needFetch bool

		m := rxRemoteRef.FindSubmatch(line)
		if m != nil {
			clNum, err := strconv.ParseInt(string(m[2]), 10, 32)
			version, ok := gerritVersionNumber(string(m[3]))
			if err != nil || !ok {
				continue
			}
			curHash := gp.remote[gerritCLVersion{int32(clNum), version}]
			needFetch = curHash != hash
		} else if trackGerritRef(refName) && gp.ref[refName] != hash {
			needFetch = true
			gp.logf("ref %q = %q", refName, sha1)
		}

		if needFetch {
			toFetch = append(toFetch, hash)
			changedRefs = append(changedRefs, &maintpb.GitRef{
				Ref:  refName,
				Sha1: string(sha1),
			})
		}
	}
	var deletedRefs []string
	for n := range gp.ref {
		if !refExists[n] {
			gp.logf("ref %q now deleted", n)
			deletedRefs = append(deletedRefs, n)
		}
	}
	c.mu.Unlock()

	if err := bs.Err(); err != nil {
		gp.logf("ls-remote scanning error: %v", err)
		return err
	}
	if len(deletedRefs) > 0 {
		c.addMutation(&maintpb.Mutation{
			Gerrit: &maintpb.GerritMutation{
				Project:     gp.proj,
				DeletedRefs: deletedRefs,
			},
		})
	}
	if len(changedRefs) == 0 {
		return nil
	}
	gp.logf("%d new refs", len(changedRefs))
	const batchSize = 250
	for len(toFetch) > 0 {
		batch := toFetch
		if len(batch) > batchSize {
			batch = batch[:batchSize]
		}
		if err := gp.fetchHashes(ctx, batch); err != nil {
			return err
		}

		c.mu.Lock()
		for _, hash := range batch {
			gp.markNeededCommit(hash)
		}
		c.mu.Unlock()

		n, err := gp.syncCommits(ctx)
		if err != nil {
			return err
		}
		toFetch = toFetch[len(batch):]
		gp.logf("synced %v commits for %d new hashes, %d hashes remain", n, len(batch), len(toFetch))

		c.addMutation(&maintpb.Mutation{
			Gerrit: &maintpb.GerritMutation{
				Project: gp.proj,
				Refs:    changedRefs[:len(batch)],
			}})
		changedRefs = changedRefs[len(batch):]
	}

	return nil
}

func (gp *GerritProject) syncCommits(ctx context.Context) (n int, err error) {
	c := gp.gerrit.c
	lastLog := time.Now()
	for {
		hash := gp.commitToIndex()
		if hash == "" {
			return n, nil
		}
		now := time.Now()
		if lastLog.Before(now.Add(-1 * time.Second)) {
			lastLog = now
			gp.logf("parsing commits (%v done)", n)
		}
		commit, err := parseCommitFromGit(gp.gitDir(), hash)
		if err != nil {
			return n, err
		}
		c.addMutation(&maintpb.Mutation{
			Gerrit: &maintpb.GerritMutation{
				Project: gp.proj,
				Commits: []*maintpb.GitCommit{commit},
			},
		})
		n++
	}
}

func (gp *GerritProject) commitToIndex() GitHash {
	c := gp.gerrit.c

	c.mu.RLock()
	defer c.mu.RUnlock()
	for hash := range gp.need {
		return hash
	}
	return ""
}

var (
	statusSpace = []byte("Status: ")
)

func (gp *GerritProject) fetchHashes(ctx context.Context, hashes []GitHash) error {
	args := []string{"fetch", "--quiet", "origin"}
	for _, hash := range hashes {
		args = append(args, hash.String())
	}
	gp.logf("fetching %v hashes...", len(hashes))
	t0 := time.Now()
	cmd := exec.CommandContext(ctx, "git", args...)
	envutil.SetDir(cmd, gp.gitDir())
	out, err := cmd.CombinedOutput()
	d := time.Since(t0).Round(time.Millisecond)
	if err != nil {
		gp.logf("error fetching %d hashes after %v: %s", len(hashes), d, out)
		return err
	}
	gp.logf("fetched %v hashes in %v", len(hashes), d)
	return nil
}

func formatExecError(err error) string {
	if ee, ok := err.(*exec.ExitError); ok {
		return fmt.Sprintf("%v; stderr=%q", err, ee.Stderr)
	}
	return fmt.Sprint(err)
}

func (gp *GerritProject) init(ctx context.Context) error {
	gitDir := gp.gitDir()
	if err := os.MkdirAll(gitDir, 0755); err != nil {
		return err
	}
	// try to short circuit a git init error, since the init error matching is
	// brittle
	if _, err := exec.LookPath("git"); err != nil {
		return fmt.Errorf("looking for git binary: %v", err)
	}

	if _, err := os.Stat(filepath.Join(gitDir, ".git", "config")); err == nil {
		cmd := exec.CommandContext(ctx, "git", "remote", "-v")
		envutil.SetDir(cmd, gitDir)
		remoteBytes, err := cmd.Output()
		if err != nil {
			return fmt.Errorf("running git remote -v in %v: %v", gitDir, formatExecError(err))
		}
		if !strings.Contains(string(remoteBytes), "origin") && !strings.Contains(string(remoteBytes), "https://"+gp.proj) {
			return fmt.Errorf("didn't find origin & gp.url in remote output %s", string(remoteBytes))
		}
		gp.logf("git directory exists.")
		return nil
	}

	cmd := exec.CommandContext(ctx, "git", "init")
	buf := new(bytes.Buffer)
	cmd.Stdout = buf
	cmd.Stderr = buf
	envutil.SetDir(cmd, gitDir)
	if err := cmd.Run(); err != nil {
		log.Printf(`Error running "git init": %s`, buf.String())
		return err
	}
	buf.Reset()
	cmd = exec.CommandContext(ctx, "git", "remote", "add", "origin", "https://"+gp.proj)
	cmd.Stdout = buf
	cmd.Stderr = buf
	envutil.SetDir(cmd, gitDir)
	if err := cmd.Run(); err != nil {
		log.Printf(`Error running "git remote add origin": %s`, buf.String())
		return err
	}

	return nil
}

// trackGerritRef reports whether we care to record changes about the
// given ref.
func trackGerritRef(ref string) bool {
	if strings.HasPrefix(ref, "refs/users/") {
		return false
	}
	if strings.HasPrefix(ref, "refs/meta/") {
		return false
	}
	if strings.HasPrefix(ref, "refs/cache-automerge/") {
		return false
	}
	return true
}

func (g *Gerrit) check() error {
	for key, gp := range g.projects {
		if err := gp.check(); err != nil {
			return fmt.Errorf("%s: %v", key, err)
		}
	}
	return nil
}

// called with its Corpus.mu locked. (called by
// Corpus.finishProcessing; read comment there)
func (g *Gerrit) finishProcessing() {
	if g == nil {
		return
	}
	for _, gp := range g.projects {
		gp.finishProcessing()
	}
}

func (gp *GerritProject) check() error {
	if len(gp.need) != 0 {
		return fmt.Errorf("%d missing commits", len(gp.need))
	}
	for hash, gc := range gp.commit {
		if gc.Committer == placeholderCommitter {
			return fmt.Errorf("git commit for key %q was placeholder", hash)
		}
		if gc.Hash != hash {
			return fmt.Errorf("git commit for key %q had GitCommit.Hash %q", hash, gc.Hash)
		}
		for _, pc := range gc.Parents {
			if _, ok := gp.commit[pc.Hash]; !ok {
				return fmt.Errorf("git commit %q exists but its parent %q does not", gc.Hash, pc.Hash)
			}
		}
	}
	return nil
}

// GerritMeta represents a Git commit in the Gerrit NoteDb meta
// format.
type GerritMeta struct {
	// Commit points up to the git commit for this Gerrit NoteDB meta commit.
	Commit *GitCommit
	// CL is the Gerrit CL this metadata is for.
	CL *GerritCL

	flags gerritMetaFlags
}

type gerritMetaFlags uint8

const (
	// metaFlagHashtagEdit indicates that the meta commit edits the hashtags on the commit.
	metaFlagHashtagEdit gerritMetaFlags = 1 << iota
)

func newGerritMeta(gc *GitCommit, cl *GerritCL) *GerritMeta {
	m := &GerritMeta{Commit: gc, CL: cl}

	if msg := m.Commit.Msg; strings.Contains(msg, "autogenerated:gerrit:setHashtag") && m.ActionTag() == "autogenerated:gerrit:setHashtag" {
		m.flags |= metaFlagHashtagEdit
	}
	return m
}

// Footer returns the "key: value" lines at the base of the commit.
func (m *GerritMeta) Footer() string {
	i := strings.LastIndex(m.Commit.Msg, "\n\n")
	if i == -1 {
		return ""
	}
	return m.Commit.Msg[i+2:]
}

// Hashtags returns the set of hashtags on m's CL as of the time of m.
func (m *GerritMeta) Hashtags() GerritHashtags {
	// If this GerritMeta set hashtags, use it.
	tags, _, ok := lineValueOK(m.Footer(), "Hashtags: ")
	if ok {
		return GerritHashtags(tags)
	}

	// Otherwise, look at older metas (from most recent to oldest)
	// to find most recent value. Ignore anything that's newer
	// than m.
	sawThisMeta := false // whether we've seen 'm'
	metas := m.CL.Metas
	for i := len(metas) - 1; i >= 0; i-- {
		mp := metas[i]
		if mp.Commit.Hash == m.Commit.Hash {
			sawThisMeta = true
			continue
		}
		if !sawThisMeta {
			continue
		}
		if tags, _, ok := lineValueOK(mp.Footer(), "Hashtags: "); ok {
			return GerritHashtags(tags)
		}
	}
	return ""
}

// ActionTag returns the Gerrit "Tag" value from the meta commit.
// These are of the form "autogenerated:gerrit:setHashtag".
func (m *GerritMeta) ActionTag() string {
	return lineValue(m.Footer(), "Tag: ")
}

// HashtagEdits returns the hashtags added and removed by this meta commit,
// and whether this meta commit actually modified hashtags.
func (m *GerritMeta) HashtagEdits() (added, removed GerritHashtags, ok bool) {
	// Return early for the majority of meta commits that don't edit hashtags.
	if m.flags&metaFlagHashtagEdit == 0 {
		return
	}

	msg := m.Commit.Msg

	// Parse lines of form:
	//
	// Hashtag removed: bar
	// Hashtags removed: foo, bar
	// Hashtag added: bar
	// Hashtags added: foo, bar
	for len(msg) > 0 {
		value, rest := lineValueRest(msg, "Hash")
		msg = rest
		colon := strings.IndexByte(value, ':')
		if colon != -1 {
			action := value[:colon]
			value := GerritHashtags(strings.TrimSpace(value[colon+1:]))
			switch action {
			case "tag added", "tags added":
				added = value
			case "tag removed", "tags removed":
				removed = value
			}
		}
	}
	ok = added != "" || removed != ""
	return
}

// HashtagsAdded returns the hashtags added by this meta commit, if any.
func (m *GerritMeta) HashtagsAdded() GerritHashtags {
	added, _, _ := m.HashtagEdits()
	return added
}

// HashtagsRemoved returns the hashtags removed by this meta commit, if any.
func (m *GerritMeta) HashtagsRemoved() GerritHashtags {
	_, removed, _ := m.HashtagEdits()
	return removed
}

// LabelVotes returns a map from label name to voter email to their vote.
//
// This is relatively expensive to call compared to other methods in maintner.
// It is not currently cached.
func (m *GerritMeta) LabelVotes() map[string]map[string]int8 {
	if m == nil {
		panic("nil *GerritMeta")
	}
	if m.CL == nil {
		panic("GerritMeta has nil CL field")
	}
	// To calculate votes as the time of the 'm' meta commit,
	// we need to consider the meta commits before it.
	// Let's see which number in the (linear) meta history
	// we are.
	ourIndex := -1
	for i, mc := range m.CL.Metas {
		if mc == m {
			ourIndex = i
			break
		}
	}
	if ourIndex == -1 {
		panic("LabelVotes called on GerritMeta not in its m.CL.Metas slice")
	}
	labels := map[string]map[string]int8{}

	history := m.CL.Metas[:ourIndex+1]
	var lastCommit string
	for _, mc := range history {
		footer := mc.Footer()
		isNew := strings.Contains(footer, "\nTag: autogenerated:gerrit:newPatchSet\n")
		email := mc.Commit.Author.Email()
		if isNew {
			if commit := lineValue(footer, "Commit: "); commit != "" {
				// TODO: implement Gerrit's vote copying. For example,
				// label.Label-Name.copyAllScoresIfNoChange defaults to true (as it is with Go's server)
				// https://gerrit-review.googlesource.com/Documentation/config-labels.html#label_copyAllScoresIfNoChange
				// We don't have the information in Maintner to do this, though.
				// One approximation is:
				if lastCommit != "" {
					oldCommit := m.CL.Project.GitCommit(lastCommit)
					newCommit := m.CL.Project.GitCommit(commit)
					if !oldCommit.SameDiffStat(newCommit) {
						// TODO: this should really use
						// the Gerrit server's project
						// config, including the
						// All-Projects config, but
						// that's not in Maintner
						// either.
						delete(labels, "Run-TryBot")
						delete(labels, "TryBot-Result")
					}
				}
				lastCommit = commit
			}
		}

		remain := footer
		for len(remain) > 0 {
			var labelEqVal string
			labelEqVal, remain = lineValueRest(remain, "Label: ")
			if labelEqVal != "" {
				label, value, whose := parseGerritLabelValue(labelEqVal)
				if label != "" {
					if whose == "" {
						whose = email
					}
					if label[0] == '-' {
						label = label[1:]
						if m := labels[label]; m != nil {
							delete(m, whose)
						}
					} else {
						m := labels[label]
						if m == nil {
							m = make(map[string]int8)
							labels[label] = m
						}
						m[whose] = value

					}
				}
			}
		}
	}

	return labels
}

// parseGerritLabelValue parses a Gerrit NoteDb "Label: ..." value.
// It can take forms and return values such as:
//
//	"Run-TryBot=+1" => ("Run-TryBot", 1, "")
//	"-Run-TryBot" => ("-Run-TryBot", 0, "")
//	"-Run-TryBot " => ("-Run-TryBot", 0, "")
//	"Run-TryBot=+1 Brad Fitzpatrick <5065@62eb7196-b449-3ce5-99f1-c037f21e1705>" =>
//	      ("Run-TryBot", 1, "5065@62eb7196-b449-3ce5-99f1-c037f21e1705")
//	"-TryBot-Result Gobot Gobot <5976@62eb7196-b449-3ce5-99f1-c037f21e1705>" =>
//	      ("-TryBot-Result", 0, "5976@62eb7196-b449-3ce5-99f1-c037f21e1705")
func parseGerritLabelValue(v string) (label string, value int8, whose string) {
	space := strings.IndexByte(v, ' ')
	if space != -1 {
		v, whose = v[:space], v[space+1:]
		if i := strings.IndexByte(whose, '<'); i == -1 {
			whose = ""
		} else {
			whose = whose[i+1:]
			if i := strings.IndexByte(whose, '>'); i == -1 {
				whose = ""
			} else {
				whose = whose[:i]
			}
		}
	}
	v = strings.TrimSpace(v)
	if eq := strings.IndexByte(v, '='); eq == -1 {
		label = v
	} else {
		label = v[:eq]
		if n, err := strconv.ParseInt(v[eq+1:], 10, 8); err == nil {
			value = int8(n)
		}
	}
	return
}

// GerritHashtags represents a set of "hashtags" on a Gerrit CL.
//
// The representation is a comma-separated string, to match Gerrit's
// internal representation in the meta commits. To support both
// forms of Gerrit's internal representation, whitespace is optional
// around the commas.
type GerritHashtags string

// Contains reports whether the hashtag t is in the set of tags s.
func (s GerritHashtags) Contains(t string) bool {
	for len(s) > 0 {
		comma := strings.IndexByte(string(s), ',')
		if comma == -1 {
			return strings.TrimSpace(string(s)) == t
		}
		if strings.TrimSpace(string(s[:comma])) == t {
			return true
		}
		s = s[comma+1:]
	}
	return false
}

// Foreach calls fn for each tag in the set s.
func (s GerritHashtags) Foreach(fn func(string)) {
	for len(s) > 0 {
		comma := strings.IndexByte(string(s), ',')
		if comma == -1 {
			fn(strings.TrimSpace(string(s)))
			return
		}
		fn(strings.TrimSpace(string(s[:comma])))
		s = s[comma+1:]
	}
}

// Match reports whether fn returns true for any tag in the set s.
// If fn returns true, iteration stops and Match returns true.
func (s GerritHashtags) Match(fn func(string) bool) bool {
	for len(s) > 0 {
		comma := strings.IndexByte(string(s), ',')
		if comma == -1 {
			return fn(strings.TrimSpace(string(s)))
		}
		if fn(strings.TrimSpace(string(s[:comma]))) {
			return true
		}
		s = s[comma+1:]
	}
	return false
}

// Len returns the number of tags in the set s.
func (s GerritHashtags) Len() int {
	if s == "" {
		return 0
	}
	return strings.Count(string(s), ",") + 1
}
