// Copyright 2022 The Dawn & Tint Authors
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
//    list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice,
//    this list of conditions and the following disclaimer in the documentation
//    and/or other materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its
//    contributors may be used to endorse or promote products derived from
//    this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package roll

import (
	"context"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"sort"
	"strconv"
	"strings"
	"sync"
	"time"

	commonAuth "dawn.googlesource.com/dawn/tools/src/auth"
	"dawn.googlesource.com/dawn/tools/src/buildbucket"
	"dawn.googlesource.com/dawn/tools/src/cmd/cts/common"
	"dawn.googlesource.com/dawn/tools/src/container"
	"dawn.googlesource.com/dawn/tools/src/cts/expectations"
	"dawn.googlesource.com/dawn/tools/src/cts/query"
	"dawn.googlesource.com/dawn/tools/src/cts/result"
	"dawn.googlesource.com/dawn/tools/src/fileutils"
	"dawn.googlesource.com/dawn/tools/src/gerrit"
	"dawn.googlesource.com/dawn/tools/src/git"
	"dawn.googlesource.com/dawn/tools/src/gitiles"
	"dawn.googlesource.com/dawn/tools/src/glob"
	"dawn.googlesource.com/dawn/tools/src/oswrapper"
	"dawn.googlesource.com/dawn/tools/src/resultsdb"
	"go.chromium.org/luci/auth"
	"go.chromium.org/luci/auth/client/authcli"
	"google.golang.org/api/sheets/v4"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/status"
)

func init() {
	common.Register(&cmd{})
}

const (
	depsRelPath    = "DEPS"
	gitLinkPath    = "third_party/webgpu-cts"
	webTestsPath   = "webgpu-cts/webtests"
	refMain        = "refs/heads/main"
	noExpectations = `# Clear all expectations to obtain full list of results`
	testQuery      = "webgpu:*"
	testFilter     = ""
)

type rollerFlags struct {
	gitPath              string
	npmPath              string
	nodePath             string
	auth                 authcli.Flags
	cacheDir             string
	ctsGitURL            string
	ctsRevision          string
	testQuery            string
	testFilter           string
	force                bool // Create a new roll, even if CTS is up to date
	rebuild              bool // Rebuild the expectations file from scratch
	preserve             bool // If false, abandon past roll changes
	sendToGardener       bool // If true, automatically send to the gardener for review
	verbose              bool
	dryRun               bool
	generateExplicitTags bool // If true, the most explicit tags will be used instead of several broad ones
	parentSwarmingRunID  string
	maxAttempts          int
}

type cmd struct {
	flags rollerFlags
}

func (c *cmd) Name() string {
	return "roll"
}

func (c *cmd) Desc() string {
	return "roll CTS and re-generate expectations"
}

func (c *cmd) RegisterFlags(ctx context.Context, cfg common.Config) ([]string, error) {
	gitPath, _ := exec.LookPath("git")
	npmPath, _ := exec.LookPath("npm")
	c.flags.auth.Register(flag.CommandLine, commonAuth.DefaultAuthOptions(cfg.OsWrapper, sheets.SpreadsheetsScope))
	flag.StringVar(&c.flags.gitPath, "git", gitPath, "path to git")
	flag.StringVar(&c.flags.npmPath, "npm", npmPath, "path to npm")
	flag.StringVar(&c.flags.nodePath, "node", fileutils.NodePath(cfg.OsWrapper), "path to node")
	flag.StringVar(&c.flags.cacheDir, "cache", common.DefaultCacheDir, "path to the results cache")
	flag.StringVar(&c.flags.ctsGitURL, "repo", cfg.Git.CTS.HttpsURL(), "the CTS source repo")
	flag.StringVar(&c.flags.ctsRevision, "revision", refMain, "revision of the CTS to roll")
	flag.StringVar(&c.flags.testQuery, "test-query", testQuery, "test query to generate test list")
	flag.StringVar(&c.flags.testFilter, "test-filter", testFilter, "glob to filter the results of the test query")
	flag.BoolVar(&c.flags.force, "force", false, "create a new roll, even if CTS is up to date")
	flag.BoolVar(&c.flags.rebuild, "rebuild", false, "rebuild the expectation file from scratch")
	flag.BoolVar(&c.flags.preserve, "preserve", false, "do not abandon existing rolls")
	flag.BoolVar(&c.flags.sendToGardener, "send-to-gardener", false, "send the CL to the WebGPU gardener for review")
	flag.BoolVar(&c.flags.verbose, "verbose", false, "emit additional logging")
	flag.BoolVar(&c.flags.dryRun, "dry-run", false, "show what would run, including the list of filtered query tests")
	flag.BoolVar(&c.flags.generateExplicitTags, "generate-explicit-tags", false,
		"Use the most explicit tags for expectations instead of several broad ones")
	flag.StringVar(&c.flags.parentSwarmingRunID, "parent-swarming-run-id", "",
		"parent swarming run id. All triggered tasks will be children of this task and will be canceled if the parent is canceled.")
	flag.IntVar(&c.flags.maxAttempts, "max-attempts", 3, "number of update attempts before giving up")
	return nil, nil
}

// TODO(crbug.com/460178080): Add unittest coverage or revise this comment once
// Gerrit interactions support dependency injection. There are other network
// interactions in this function that also need dependency injection, so
// unittest coverage is blocked until all support that.
func (c *cmd) Run(ctx context.Context, cfg common.Config) error {
	// Validate command line arguments
	options, err := c.flags.auth.Options()
	if err != nil {
		return fmt.Errorf("failed to obtain authentication options: %w", err)
	}

	// Check tools can be found
	for _, tool := range []struct {
		name, path, hint string
	}{
		{name: "git", path: c.flags.gitPath},
		{name: "npm", path: c.flags.npmPath},
		{name: "node", path: c.flags.nodePath},
	} {
		if _, err := cfg.OsWrapper.Stat(tool.path); err != nil {
			return fmt.Errorf("failed to find path to %v: %v. %v", tool.name, err, tool.hint)
		}
	}

	// Create the various service clients and ensure required permissions are
	// available.
	gitInstance, err := git.New(c.flags.gitPath, cfg.OsWrapper)
	if err != nil {
		return fmt.Errorf("failed to obtain authentication options: %w", err)
	}
	gerritInstance, err := gerrit.New(ctx, options, cfg.Gerrit.Host)
	if err != nil {
		return err
	}
	dawn, err := gitiles.New(ctx, cfg.Git.Dawn.Host, cfg.Git.Dawn.Project)
	if err != nil {
		return err
	}
	bb, err := buildbucket.New(ctx, options)
	if err != nil {
		return err
	}
	client, err := resultsdb.NewBigQueryClient(ctx, resultsdb.DefaultQueryProject)
	if err != nil {
		return err
	}
	cfg.Querier = client

	credCheckInput := common.CredCheckInputs{
		// TODO(crbug.com/349798588): Re-enable this check once we figure out why
		// the roller is reporting that it cannot upload to Gerrit.
		GerritConfig:  nil,
		GitilesConfig: dawn,
		Querier:       client,
	}
	err = common.CheckAllRequiredCredentials(ctx, credCheckInput)
	if err != nil {
		return err
	}

	// Create a temporary directory for local checkouts
	tmpDir, err := cfg.OsWrapper.MkdirTemp("", "dawn-cts-roll")
	if err != nil {
		return err
	}
	defer cfg.OsWrapper.RemoveAll(tmpDir)
	ctsDir := filepath.Join(tmpDir, "cts")

	// Construct the roller, and roll
	r := roller{
		cfg:                 cfg,
		flags:               c.flags,
		auth:                options,
		bb:                  bb,
		parentSwarmingRunID: c.flags.parentSwarmingRunID,
		git:                 gitInstance,
		gerrit:              gerritInstance,
		gitiles:             gitilesRepos{dawn: dawn},
		ctsDir:              ctsDir,
	}
	return r.roll(ctx)
}

type gitilesRepos struct {
	dawn *gitiles.Gitiles
}

type roller struct {
	cfg                 common.Config
	flags               rollerFlags
	auth                auth.Options
	bb                  *buildbucket.Buildbucket
	parentSwarmingRunID string
	git                 *git.Git
	gerrit              *gerrit.Gerrit
	gitiles             gitilesRepos
	ctsDir              string
}

// TODO(crbug.com/344014313): Split this up into helper functions and add
// unittest coverage after code this depends on switches to using dependency
// injection.
func (r *roller) roll(ctx context.Context) error {
	// Fetch the latest Dawn main revision
	dawnHash, err := r.gitiles.dawn.Hash(ctx, refMain)
	if err != nil {
		return err
	}

	// Checkout the CTS at the latest revision
	ctsRepo, err := r.checkout("cts", r.ctsDir, r.flags.ctsGitURL, r.flags.ctsRevision)
	if err != nil {
		return err
	}

	// Obtain the target CTS revision hash
	ctsRevisionLog, err := ctsRepo.Log(&git.LogOptions{From: r.flags.ctsRevision + "^", To: r.flags.ctsRevision})
	if err != nil {
		return err
	}
	newCTSHash := ctsRevisionLog[0].Hash.String()

	// Update the DEPS file
	updatedDEPS, oldCTSHash, err := r.updateDEPS(ctx, dawnHash, newCTSHash)
	if err != nil {
		return err
	}
	if newCTSHash == oldCTSHash && !r.flags.force {
		// Already up to date
		fmt.Println("CTS is already up to date")
		return nil
	}

	log.Printf("starting CTS roll from %v to %v...", oldCTSHash[:8], newCTSHash[:8])

	// Fetch the log of changes between last roll and now
	ctsLog, err := ctsRepo.Log(&git.LogOptions{From: oldCTSHash, To: newCTSHash})
	if err != nil {
		return err
	}
	ctsLog = ctsLog[:len(ctsLog)-1] // Don't include the oldest change in the log

	type ExpectationsFileInfo struct {
		path            string
		expectations    expectations.Content
		newExpectations expectations.Content
		executionMode   result.ExecutionMode
		results         result.List
	}

	var exInfos = []*ExpectationsFileInfo{
		{
			path:          common.RelativeExpectationsPath,
			executionMode: "core",
			results:       result.List{},
		},
		{
			path:          common.RelativeCompatExpectationsPath,
			executionMode: "compat",
			results:       result.List{},
		},
	}

	// Download and parse the expectations files
	for _, exInfo := range exInfos {
		expectationsFile, err := r.gitiles.dawn.DownloadFile(ctx, refMain, exInfo.path)
		if err != nil {
			return err
		}
		ex, err := expectations.Parse(exInfo.path, expectationsFile)
		if err != nil {
			return fmt.Errorf("failed to load expectations: %v", err)
		}

		// If the user requested a full rebuild of the expectations, strip out
		// everything but comment chunks.
		if r.flags.rebuild {
			rebuilt := ex.Clone()
			rebuilt.Chunks = rebuilt.Chunks[:0]
			for _, c := range ex.Chunks {
				if c.IsCommentOnly() {
					rebuilt.Chunks = append(rebuilt.Chunks, c)
				}
			}
			ex = rebuilt
		}

		exInfo.expectations = ex
	}

	generatedFiles, err := func(ctx context.Context, osWrapper oswrapper.OSWrapper) (map[string]string, error) {
		generatedFiles, err := r.generateFiles(ctx, r.cfg.OsWrapper)
		if err != nil {
			return nil, err
		}

		if r.flags.testFilter != "" {
			log.Printf("filtering test list...")
			// Filter the test list in place. This way it will get used after
			// being filtered and written as filtered.
			newLines := []string{}
			lines := strings.Split(generatedFiles[common.TestListRelPath], "\n")
			for _, line := range lines {
				matched, err := filepath.Match(r.flags.testFilter, line)
				if err != nil {
					return nil, fmt.Errorf("error using test-filter '%s': %v", r.flags.testFilter, err)
				}
				if matched {
					newLines = append(newLines, line)
				}
			}
			if len(newLines) == 0 {
				return nil, fmt.Errorf("test-query and test-filter produced 0 tests")
			}
			generatedFiles[common.TestListRelPath] = strings.Join(newLines, "\n")
		}
		return generatedFiles, nil
	}(ctx, r.cfg.OsWrapper)
	if err != nil {
		return err
	}

	if r.flags.dryRun {
		log.Printf("Filtered Queried Test List:")
		log.Printf(generatedFiles[common.TestListRelPath])
	}

	// Pull out the test list from the generated files
	testlist := func() []query.Query {
		lines := strings.Split(generatedFiles[common.TestListRelPath], "\n")
		list := make([]query.Query, len(lines))
		for i, line := range lines {
			list[i] = query.Parse(line)
		}
		return list
	}()

	// Remove any expectations that are for tests that no longer exist.
	for _, exInfo := range exInfos {
		(&exInfo.expectations).RemoveExpectationsForUnknownTests(&testlist)
	}

	deletedFiles := []string{}
	if currentWebTestFiles, err := r.gitiles.dawn.ListFiles(ctx, dawnHash, webTestsPath); err != nil {
		// If there's an error, allow NotFound. It means the directory did not exist, so no files
		// need to be deleted.
		if e, ok := status.FromError(err); !ok || e.Code() != codes.NotFound {
			return fmt.Errorf("listing current web tests failed: %v", err)
		}

		for _, f := range currentWebTestFiles {
			// If the file is not generated in this revision, and it is an .html file,
			// mark it for deletion.
			if !strings.HasSuffix(f, ".html") {
				continue
			}
			if _, exists := generatedFiles[f]; !exists {
				deletedFiles = append(deletedFiles, f)
			}
		}
	}

	// Look for an existing gerrit change to update
	existingRolls, err := r.findExistingRolls()
	if err != nil {
		return err
	}

	// Abandon existing rolls, if -preserve is false
	if !r.flags.preserve && len(existingRolls) > 0 {
		log.Printf("abandoning %v existing roll...", len(existingRolls))
		if !r.flags.dryRun {
			for _, change := range existingRolls {
				if err := r.gerrit.Abandon(change.ChangeID); err != nil {
					return err
				}
			}
		}
		existingRolls = nil
	}

	// Create a new gerrit change, if needed
	changeID := ""
	if r.flags.preserve || len(existingRolls) == 0 {
		msg := r.rollCommitMessage(oldCTSHash, newCTSHash, ctsLog, "")
		if r.flags.dryRun {
			changeID = "dry-run-id"
			log.Printf("created gerrit change (dry-run)...\n%s", msg)
		} else {
			change, err := r.gerrit.CreateChange(r.cfg.Gerrit.Project, "main", msg, true)
			if err != nil {
				return err
			}
			changeID = change.ID
			log.Printf("created gerrit change %v (%v)...", change.Number, change.URL)
		}
	} else {
		changeID = existingRolls[0].ID
		log.Printf("reusing existing gerrit change %v (%v)...", existingRolls[0].Number, existingRolls[0].URL)
	}

	if r.flags.dryRun {
		log.Printf("dry run exit")
		return nil
	}

	// Update the DEPS, expectations, and other generated files.
	for _, exInfo := range exInfos {
		updateExpectationUpdateTimestamp(&exInfo.expectations)
		generatedFiles[exInfo.path] = exInfo.expectations.String()
	}
	generatedFiles[depsRelPath] = updatedDEPS
	generatedFiles[gitLinkPath] = newCTSHash

	msg := r.rollCommitMessage(oldCTSHash, newCTSHash, ctsLog, changeID)
	ps, err := r.gerrit.EditFiles(changeID, msg, generatedFiles, deletedFiles)
	if err != nil {
		return fmt.Errorf("failed to update change '%v': %v", changeID, err)
	}

	var psResultsByExecutionMode result.ResultsByExecutionMode

	defer func() {
		// Export the results to the Google Sheets whether the roll succeeded or failed.
		if psResultsByExecutionMode != nil {
			log.Println("exporting results...")
			if err := common.Export(ctx, r.auth, r.cfg.Sheets.ID, r.ctsDir, r.flags.nodePath, r.flags.npmPath, psResultsByExecutionMode); err != nil {
				log.Println("failed to update results spreadsheet (expected if running locally): ", err)
			}
		}
	}()

	// Begin main roll loop
	for attempt := 0; ; attempt++ {
		// Kick builds
		log.Printf("building (pass %v)...\n", attempt+1)
		builds, err := common.GetOrStartBuildsAndWait(ctx, r.cfg, ps, r.bb, r.parentSwarmingRunID, false)
		if err != nil {
			return err
		}

		// Look to see if any of the builds failed
		failingBuilds := []string{}
		for id, build := range builds {
			if build.Status != buildbucket.StatusSuccess {
				failingBuilds = append(failingBuilds, id)
			}
		}
		if len(failingBuilds) > 0 {
			sort.Strings(failingBuilds)
			log.Println("builds failed: ", failingBuilds)
		}

		// Gather the build results
		log.Println("gathering results...")
		psResultsByExecutionMode, err = common.CacheUnsuppressedFailingResults(ctx, r.cfg, ps, r.flags.cacheDir, builds)
		if err != nil {
			return err
		}

		// If all the builds attempted, and we updated the expectations at least once, then we're done!
		if attempt > 0 && len(failingBuilds) == 0 {
			break
		}

		// Rebuild the expectations with the accumulated results
		log.Println("building new expectations...")
		for _, exInfo := range exInfos {
			// TODO(crbug.com/372730248): Modify exInfo.expectations in place once
			// the old code path is removed.
			exInfo.newExpectations = exInfo.expectations.Clone()
			err := exInfo.newExpectations.AddExpectationsForFailingResults(psResultsByExecutionMode[exInfo.executionMode],
				r.flags.generateExplicitTags, r.flags.verbose)
			if err != nil {
				return err
			}
			exInfo.expectations = exInfo.newExpectations
		}

		// Otherwise, push the updated expectations, and try again
		log.Println("updating expectations...")

		editedFiles := map[string]string{}
		for _, exInfo := range exInfos {
			updateExpectationUpdateTimestamp(&exInfo.newExpectations)
			editedFiles[exInfo.path] = exInfo.newExpectations.String()
		}
		ps, err = r.gerrit.EditFiles(changeID, msg, editedFiles, nil)
		if err != nil {
			return fmt.Errorf("failed to update change '%v': %v", changeID, err)
		}

		if attempt >= r.flags.maxAttempts {
			err := fmt.Errorf("CTS failed after %v retries.\nGiving up", attempt)
			r.gerrit.Comment(ps, err.Error(), nil)
			return err
		}
	}

	reviewer := ""
	if r.flags.sendToGardener {
		resp, err := http.Get("https://chrome-ops-rotation-proxy.appspot.com/current/grotation:webgpu-gardener")
		if err != nil {
			return err
		}
		defer resp.Body.Close()

		jsonResponse, err := io.ReadAll(resp.Body)
		if err != nil {
			return err
		}

		type StructuredJSONResponse struct {
			Emails []string
		}
		var jsonRes StructuredJSONResponse
		if err := json.Unmarshal(jsonResponse, &jsonRes); err != nil {
			return err
		}
		if len(jsonRes.Emails) < 1 {
			return fmt.Errorf("expected at least one email in JSON response %s", jsonRes)
		}
		reviewer = jsonRes.Emails[0]
	}

	if err := r.gerrit.SetReadyForReview(changeID, "CTS roll succeeded", reviewer); err != nil {
		return fmt.Errorf("failed to mark change as ready for review: %v", err)
	}

	return nil
}

// Updates the '# Last rolled:' string in the expectations file.
func updateExpectationUpdateTimestamp(content *expectations.Content) {
	prefix := "# Last rolled: "
	comment := prefix + time.Now().UTC().Format("2006-01-02 03:04:05PM")
	for _, chunk := range content.Chunks {
		for l, line := range chunk.Comments {
			if strings.HasPrefix(line, prefix) {
				chunk.Comments[l] = comment
				return
			}
		}
	}
	newChunks := []expectations.Chunk{}
	if len(content.Chunks) > 0 {
		newChunks = append(newChunks,
			content.Chunks[0],
			expectations.Chunk{},
		)
	}
	newChunks = append(newChunks,
		expectations.Chunk{Comments: []string{comment}},
	)
	if len(content.Chunks) > 0 {
		newChunks = append(newChunks, content.Chunks[1:]...)
	}

	content.Chunks = newChunks
}

// rollCommitMessage returns the commit message for the roll
func (r *roller) rollCommitMessage(
	oldCTSHash, newCTSHash string,
	ctsLog []git.CommitInfo,
	changeID string) string {

	isExternalRepo := r.flags.ctsGitURL != r.cfg.Git.CTS.HttpsURL()

	msg := &strings.Builder{}
	if isExternalRepo {
		// note: intentionally split to fool the pre-submit checks!
		msg.WriteString("[DO NOT")
		msg.WriteString(" SUBMIT] ")
	}
	msg.WriteString(common.RollSubjectPrefix)
	msg.WriteString(oldCTSHash[:9])
	msg.WriteString("..")
	msg.WriteString(newCTSHash[:9])
	msg.WriteString(" (")
	msg.WriteString(strconv.Itoa(len(ctsLog)))
	if len(ctsLog) == 1 {
		msg.WriteString(" commit)")
	} else {
		msg.WriteString(" commits)")
	}
	msg.WriteString("\n\n")
	if isExternalRepo {
		msg.WriteString("Rolled from external repo: ")
		msg.WriteString(r.flags.ctsGitURL)
		msg.WriteString("\n\n")
	}
	msg.WriteString("Regenerated:\n")
	msg.WriteString(" - expectations.txt\n")
	msg.WriteString(" - compat-expectations.txt\n")
	msg.WriteString(" - ts_sources.txt\n")
	msg.WriteString(" - test_list.txt\n")
	msg.WriteString(" - resource_files.txt\n")
	msg.WriteString(" - webtest .html files\n")
	msg.WriteString("\n\n")
	msg.WriteString("https://chromium.googlesource.com/external/github.com/gpuweb/cts/+log/")
	msg.WriteString(oldCTSHash[:12])
	msg.WriteString("..")
	msg.WriteString(newCTSHash[:12])
	msg.WriteString("\n")
	for _, change := range ctsLog {
		msg.WriteString(" - ")
		msg.WriteString(change.Hash.String()[:6])
		msg.WriteString(" ")
		msg.WriteString(change.Subject)
		msg.WriteString("\n")
	}
	msg.WriteString("\n")
	msg.WriteString("Created with './tools/run cts roll'")
	msg.WriteString("\n")
	msg.WriteString("\n")
	if len(r.cfg.Builders) > 0 {
		msg.WriteString("Cq-Include-Trybots: ")
		buildersByBucket := container.NewMap[string, []string]()
		for _, build := range r.cfg.Builders {
			key := fmt.Sprintf("luci.%v.%v", build.Project, build.Bucket)
			buildersByBucket[key] = append(buildersByBucket[key], build.Builder)
		}
		first := true
		for _, bucket := range buildersByBucket.Keys() {
			// Cq-Include-Trybots: luci.chromium.try:win-dawn-rel;luci.dawn.try:mac-dbg,mac-rel
			if !first {
				msg.WriteString(";")
			}
			first = false
			msg.WriteString(bucket)
			msg.WriteString(":")
			builders := buildersByBucket[bucket]
			sort.Strings(builders)
			msg.WriteString(strings.Join(builders, ","))
		}
		msg.WriteString("\n")
	}
	msg.WriteString("Include-Ci-Only-Tests: true\n")
	if isExternalRepo {
		msg.WriteString("Commit: false\n")
	}
	if changeID != "" {
		msg.WriteString("Change-Id: ")
		msg.WriteString(changeID)
		msg.WriteString("\n")
	}

	return msg.String()
}

// TODO(crbug.com/460178080): Add unittests for this once Gerrit interactions
// support dependency injection.
// findExistingRolls looks for all existing open CTS rolls by this user
func (r *roller) findExistingRolls() ([]gerrit.ChangeInfo, error) {
	// Look for an existing gerrit change to update
	changes, _, err := r.gerrit.QueryChanges("owner:me",
		"is:open",
		fmt.Sprintf(`repo:"%v"`, r.cfg.Git.Dawn.Project),
		fmt.Sprintf(`message:"%v"`, common.RollSubjectPrefix))
	if err != nil {
		return nil, fmt.Errorf("failed to find existing roll gerrit changes: %v", err)
	}
	return changes, nil
}

// TODO(crbug.com/416755658): Add unittest coverage for this once the repo
// exec uses are handled via dependency injection.
// checkout performs a git checkout of the repo at host to dir at the given hash
func (r *roller) checkout(project, dir, host, hash string) (*git.Repository, error) {
	log.Printf("cloning %v to '%v'...", project, dir)
	repo, err := r.git.Clone(dir, host, &git.CloneOptions{Timeout: time.Minute * 10})
	if err != nil {
		return nil, fmt.Errorf("failed to clone %v: %v", project, err)
	}
	log.Printf("checking out %v @ '%v'...", project, hash)
	if _, err := repo.Fetch(hash, nil); err != nil {
		return nil, fmt.Errorf("failed to fetch project %v @ %v: %v",
			project, hash, err)
	}
	if err := repo.Checkout(hash, nil); err != nil {
		return nil, fmt.Errorf("failed to checkout project %v @ %v: %v",
			project, hash, err)
	}
	return repo, nil
}

// TODO(crbug.com/416755658): Add unittest coverage for this once InstallCTSDeps
// supports dependency injection.
// Call 'npm ci' in the CTS directory, and generates a map of project-relative
// file path to file content for the CTS roll's change. This includes:
// * type-script source files
// * CTS test list
// * resource file list
// * webtest file sources
func (r *roller) generateFiles(ctx context.Context, fsReader oswrapper.FilesystemReader) (map[string]string, error) {
	// Run 'npm ci' to fetch modules and tsc
	if err := common.InstallCTSDeps(ctx, r.ctsDir, r.flags.npmPath); err != nil {
		return nil, err
	}

	log.Printf("generating files for changelist...")

	// Run the below concurrently
	mutex := sync.Mutex{}
	files := map[string]string{} // guarded by mutex
	wg := sync.WaitGroup{}

	errs := make(chan error, 8)

	// Generate web tests HTML files
	wg.Add(1)
	go func() {
		defer wg.Done()
		if out, err := r.genWebTestSources(ctx, fsReader); err == nil {
			mutex.Lock()
			defer mutex.Unlock()
			for file, content := range out {
				files[file] = content
			}
		} else {
			errs <- fmt.Errorf("failed to generate web tests: %v", err)
		}
	}()

	// Generate typescript sources list, test list, resources file list.
	for relPath, generator := range map[string]func(
		context.Context, oswrapper.FilesystemReader) (string, error){

		common.TsSourcesRelPath:     r.genTSDepList,
		common.TestListRelPath:      r.genTestList,
		common.ResourceFilesRelPath: r.genResourceFilesList,
	} {
		relPath, generator := relPath, generator // Capture values, not iterators
		wg.Add(1)
		go func() {
			defer wg.Done()
			if out, err := generator(ctx, fsReader); err == nil {
				mutex.Lock()
				defer mutex.Unlock()
				files[relPath] = out
			} else {
				errs <- fmt.Errorf("failed to generate %v: %v", relPath, err)
			}
		}()
	}

	// Wait for all the above to complete
	wg.Wait()
	close(errs)

	// Check for errors
	for err := range errs {
		return nil, err
	}

	return files, nil
}

// TODO(crbug.com/416731783): Add unittest coverage for this once gitiles
// network interactions can be mocked out via dependency injection.
// updateDEPS fetches and updates the Dawn DEPS file at 'dawnRef' so that all CTS hashes are changed to newCTSHash
func (r *roller) updateDEPS(ctx context.Context, dawnRef, newCTSHash string) (newDEPS, oldCTSHash string, err error) {
	deps, err := r.gitiles.dawn.DownloadFile(ctx, dawnRef, depsRelPath)
	if err != nil {
		return "", "", err
	}
	newDEPS, oldCTSHash, err = common.UpdateCTSHashInDeps(deps, r.flags.ctsGitURL, newCTSHash)
	if err != nil {
		return "", "", err
	}

	return newDEPS, oldCTSHash, nil
}

// TODO(crbug.com/416755658): Add unittest coverage once exec calls are handled
// via dependency injection.
// genTSDepList returns a list of source files, for the CTS checkout at r.ctsDir
// This list can be used to populate the ts_sources.txt file.
// Requires tsc to be found at './node_modules/.bin/tsc' in the CTS directory
// (e.g. must be called post 'npm ci')
func (r *roller) genTSDepList(
	ctx context.Context, fsReader oswrapper.FilesystemReader) (string, error) {

	tscPath := filepath.Join(r.ctsDir, "node_modules/.bin/tsc")
	if !fileutils.IsExe(tscPath, fsReader) {
		return "", fmt.Errorf("tsc not found at '%v'", tscPath)
	}

	cmd := exec.CommandContext(ctx, tscPath, "--project",
		filepath.Join(r.ctsDir, "tsconfig.json"),
		"--listFiles",
		"--declaration", "false",
		"--sourceMap", "false")

	// Note: we're ignoring the error for this as tsc typically returns status 2.
	out, _ := cmd.Output()

	prefix := filepath.ToSlash(r.ctsDir) + "/"

	deps := []string{}
	for _, line := range strings.Split(string(out), "\n") {
		if strings.HasPrefix(line, prefix) {
			line = line[len(prefix):]
			if strings.HasPrefix(line, "src/") {
				deps = append(deps, line)
			}
		}
	}

	return strings.Join(deps, "\n") + "\n", nil
}

// TODO(crbug.com/416755658): Add unittest coverage once GetnTestList supports
// dependency injection for exec calls.
// genTestList returns the newline delimited list of test names, for the CTS checkout at r.ctsDir
func (r *roller) genTestList(
	ctx context.Context, fsReader oswrapper.FilesystemReader) (string, error) {

	return common.GenTestList(ctx, r.ctsDir, r.flags.nodePath, r.flags.testQuery)
}

// genResourceFilesList returns a list of resource files, for the CTS checkout at r.ctsDir
// This list can be used to populate the resource_files.txt file.
func (r *roller) genResourceFilesList(
	ctx context.Context, fsReader oswrapper.FilesystemReader) (string, error) {

	dir := filepath.Join(r.ctsDir, "src", "resources")
	files, err := glob.Glob(filepath.Join(dir, "**"), fsReader)
	if err != nil {
		return "", err
	}
	for i, file := range files {
		file, err := filepath.Rel(dir, file)
		if err != nil {
			return "", err
		}
		files[i] = file
	}
	return strings.Join(files, "\n") + "\n", nil
}

// genWebTestSources returns a map of generated webtest file names to contents, for the CTS checkout at r.ctsDir
func (r *roller) genWebTestSources(ctx context.Context, fsReader oswrapper.FilesystemReader) (map[string]string, error) {
	generatedFiles := map[string]string{}
	htmlSearchDir := filepath.Join(r.ctsDir, "src", "webgpu")
	err := fsReader.Walk(htmlSearchDir,
		func(path string, info os.FileInfo, err error) error {
			if err != nil {
				return err
			}
			if !strings.HasSuffix(info.Name(), ".html") || info.IsDir() {
				return nil
			}
			relPath, err := filepath.Rel(htmlSearchDir, path)
			if err != nil {
				return err
			}

			data, err := fsReader.ReadFile(path)
			if err != nil {
				return err
			}
			contents := string(data)

			// Find the index after the starting html tag.
			i := strings.Index(contents, "<html")
			if i < 0 {
				return fmt.Errorf("Unable to find starting HTML tag in %s", path)
			}
			i = i + strings.Index(contents[i:], ">")
			i = i + 1

			// Insert a base tag so the fetched resources will come from the generated CTS JavaScript sources.
			contents = contents[:i] + "\n" + `  <base ref="/gen/third_party/dawn/webgpu-cts/src/webgpu" />` + contents[i:]

			generatedFiles[filepath.Join(webTestsPath, relPath)] = contents
			return nil
		})
	if err != nil {
		return nil, err
	}
	return generatedFiles, nil
}
