package web

import (
	"bytes"
	"context"
	"crypto/md5"
	"encoding/hex"
	"fmt"
	"image"
	"image/png"
	"net/http"
	"net/url"
	"path"
	"sort"
	"strings"
	"sync"
	"time"

	"github.com/cockroachdb/cockroach-go/v2/crdb/crdbpgx"
	"github.com/google/uuid"
	"github.com/gorilla/mux"
	lru "github.com/hashicorp/golang-lru"
	"github.com/jackc/pgtype"
	"github.com/jackc/pgx/v4"
	"github.com/jackc/pgx/v4/pgxpool"
	"go.opencensus.io/trace"
	"golang.org/x/sync/errgroup"
	"golang.org/x/time/rate"

	"go.skia.org/infra/go/httputils"
	"go.skia.org/infra/go/human"
	"go.skia.org/infra/go/login"
	"go.skia.org/infra/go/now"
	"go.skia.org/infra/go/paramtools"
	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/util"
	"go.skia.org/infra/golden/go/clstore"
	"go.skia.org/infra/golden/go/diff"
	"go.skia.org/infra/golden/go/expectations"
	"go.skia.org/infra/golden/go/ignore"
	"go.skia.org/infra/golden/go/search"
	search_query "go.skia.org/infra/golden/go/search/query"
	"go.skia.org/infra/golden/go/sql"
	"go.skia.org/infra/golden/go/sql/schema"
	"go.skia.org/infra/golden/go/storage"
	"go.skia.org/infra/golden/go/types"
	"go.skia.org/infra/golden/go/validation"
	"go.skia.org/infra/golden/go/web/frontend"
)

const (
	// pageSize is the default page size used for pagination.
	pageSize = 20

	// maxPageSize is the maximum page size used for pagination.
	maxPageSize = 100

	// These params limit how anonymous (not logged-in) users can hit various endpoints.
	// We have two buckets of requests - cheap and expensive. Expensive stuff hits a database
	// or similar, where as cheap stuff is cached. These limits are shared by *all* endpoints
	// in a given bucket. See skbug.com/9476 for more.
	maxAnonQPSExpensive   = rate.Limit(0.01)
	maxAnonBurstExpensive = 50
	maxAnonQPSCheap       = rate.Limit(5.0)
	maxAnonBurstCheap     = 50
	// Special settings for RPCs serving the gerrit plugin. See skbug.com/10768 for more.
	maxAnonQPSGerritPlugin   = rate.Limit(200.0)
	maxAnonBurstGerritPlugin = 1000

	changelistSummaryCacheSize = 10000

	// RPCCallCounterMetric is the metric that should be used when counting how many times a given
	// RPC route is called from clients.
	RPCCallCounterMetric = "gold_rpc_call_counter"
)

type validateFields int

const (
	// FullFrontEnd means all fields should be set
	FullFrontEnd validateFields = iota
	// BaselineSubset means just the fields needed for BaselineV2Response Server should be set.
	BaselineSubset
)

// HandlersConfig holds the environment needed by the various http handler functions.
type HandlersConfig struct {
	DB            *pgxpool.Pool
	GCSClient     storage.GCSClient
	IgnoreStore   ignore.Store
	ReviewSystems []clstore.ReviewSystem
	Search2API    search.API
	WindowSize    int
}

// Handlers represents all the handlers (e.g. JSON endpoints) of Gold.
// It should be created by clients using NewHandlers.
type Handlers struct {
	HandlersConfig

	anonymousExpensiveQuota *rate.Limiter
	anonymousCheapQuota     *rate.Limiter
	anonymousGerritQuota    *rate.Limiter

	clSummaryCache *lru.Cache

	statusCache      frontend.GUIStatus
	statusCacheMutex sync.RWMutex

	ignoredTracesCache      []ignoredTrace
	ignoredTracesCacheMutex sync.RWMutex

	knownHashesMutex sync.RWMutex
	knownHashesCache string

	// These can be set for unit tests to simplify the testing.
	testingAuthAs string
}

// NewHandlers returns a new instance of Handlers.
func NewHandlers(conf HandlersConfig, val validateFields) (*Handlers, error) {
	// These fields are required by all types.
	if conf.DB == nil {
		return nil, skerr.Fmt("Baseliner cannot be nil")
	}
	if conf.GCSClient == nil {
		return nil, skerr.Fmt("GCSClient cannot be nil")
	}

	if val == FullFrontEnd {
		if conf.IgnoreStore == nil {
			return nil, skerr.Fmt("IgnoreStore cannot be nil")
		}
		if conf.Search2API == nil {
			return nil, skerr.Fmt("Search2API cannot be nil")
		}
	}

	clcache, err := lru.New(changelistSummaryCacheSize)
	if err != nil {
		return nil, skerr.Wrap(err)
	}

	return &Handlers{
		HandlersConfig:          conf,
		anonymousExpensiveQuota: rate.NewLimiter(maxAnonQPSExpensive, maxAnonBurstExpensive),
		anonymousCheapQuota:     rate.NewLimiter(maxAnonQPSCheap, maxAnonBurstCheap),
		anonymousGerritQuota:    rate.NewLimiter(maxAnonQPSGerritPlugin, maxAnonBurstGerritPlugin),
		clSummaryCache:          clcache,
		testingAuthAs:           "", // Just to be explicit that we do *not* bypass Auth.
	}, nil
}

// limitForAnonUsers blocks using the configured rate.Limiter for expensive queries.
func (wh *Handlers) limitForAnonUsers(r *http.Request) error {
	if login.LoggedInAs(r) != "" {
		return nil
	}
	return wh.anonymousExpensiveQuota.Wait(r.Context())
}

// cheapLimitForAnonUsers blocks using the configured rate.Limiter for cheap queries.
func (wh *Handlers) cheapLimitForAnonUsers(r *http.Request) error {
	if login.LoggedInAs(r) != "" {
		return nil
	}
	return wh.anonymousCheapQuota.Wait(r.Context())
}

// cheapLimitForGerritPlugin blocks using the configured rate.Limiter for queries for the
// Gerrit Plugin.
func (wh *Handlers) cheapLimitForGerritPlugin(r *http.Request) error {
	if login.LoggedInAs(r) != "" {
		return nil
	}
	return wh.anonymousGerritQuota.Wait(r.Context())
}

// ByBlameHandler takes the response from the SQL backend's GetBlamesForUntriagedDigests and
// converts it into the same format that the legacy version (v1) produced.
func (wh *Handlers) ByBlameHandler(w http.ResponseWriter, r *http.Request) {
	if err := wh.limitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}
	ctx, span := trace.StartSpan(r.Context(), "web_ByBlameHandler", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()

	// Extract the corpus from the query parameters.
	corpus := ""
	if v := r.FormValue("query"); v != "" {
		if qp, err := url.ParseQuery(v); err != nil {
			httputils.ReportError(w, err, "invalid input", http.StatusBadRequest)
			return
		} else if corpus = qp.Get(types.CorpusField); corpus == "" {
			// If no corpus specified report an error.
			http.Error(w, "did not receive value for corpus", http.StatusBadRequest)
			return
		}
	} else {
		// If no corpus specified report an error.
		http.Error(w, "did not receive value for search query", http.StatusBadRequest)
		return
	}
	summary, err := wh.Search2API.GetBlamesForUntriagedDigests(ctx, corpus)
	if err != nil {
		httputils.ReportError(w, err, "Could not compute blames", http.StatusInternalServerError)
		return
	}
	result := frontend.ByBlameResponse{}
	for _, sr := range summary.Ranges {
		entry := frontend.ByBlameEntry{
			GroupID:  sr.CommitRange,
			NDigests: sr.TotalUntriagedDigests,
			NTests:   len(sr.AffectedGroupings),
			Commits:  sr.Commits,
		}
		var groupings []frontend.TestRollup
		for _, gr := range sr.AffectedGroupings {
			groupings = append(groupings, frontend.TestRollup{
				Test:         types.TestName(gr.Grouping[types.PrimaryKeyField]),
				Num:          gr.UntriagedDigests,
				SampleDigest: gr.SampleDigest,
			})
		}
		entry.AffectedTests = groupings
		result.Data = append(result.Data, entry)
	}
	sendJSONResponse(w, result)
}

// ChangelistsHandler returns the list of code_review.Changelists that have
// uploaded results to Gold (via TryJobs).
func (wh *Handlers) ChangelistsHandler(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_ChangelistsHandler", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()
	if err := wh.cheapLimitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}

	values := r.URL.Query()
	offset, size, err := httputils.PaginationParams(values, 0, pageSize, maxPageSize)
	if err != nil {
		httputils.ReportError(w, err, "Invalid pagination params.", http.StatusInternalServerError)
		return
	}

	_, activeOnly := values["active"]
	cls, pagination, err := wh.getIngestedChangelists2(ctx, offset, size, activeOnly)

	if err != nil {
		httputils.ReportError(w, err, "Retrieving changelists results failed.", http.StatusInternalServerError)
		return
	}

	response := frontend.ChangelistsResponse{
		Changelists:        cls,
		ResponsePagination: pagination,
	}

	sendJSONResponse(w, response)
}

func (wh *Handlers) getIngestedChangelists2(ctx context.Context, offset, size int, activeOnly bool) ([]frontend.Changelist, httputils.ResponsePagination, error) {
	ctx, span := trace.StartSpan(ctx, "web_getIngestedChangelists2")
	defer span.End()

	statement := `SELECT changelist_id, system, status, owner_email, subject, last_ingested_data
FROM Changelists AS OF SYSTEM TIME '-0.1s'`
	if activeOnly {
		statement += " WHERE status = 'open'"
	} else {
		// This lets us use the same statusIngestedIndex
		statement += " WHERE status = ANY('open', 'landed', 'abandoned')"
	}
	statement += ` ORDER BY last_ingested_data DESC OFFSET $1 LIMIT $2`
	rows, err := wh.DB.Query(ctx, statement, offset, size)
	if err != nil {
		return nil, httputils.ResponsePagination{}, skerr.Wrap(err)
	}
	defer rows.Close()
	var rv []frontend.Changelist
	for rows.Next() {
		var cl frontend.Changelist
		var qCLID string
		if err := rows.Scan(&qCLID, &cl.System, &cl.Status, &cl.Owner, &cl.Subject, &cl.Updated); err != nil {
			return nil, httputils.ResponsePagination{}, skerr.Wrap(err)
		}
		cl.Updated = cl.Updated.UTC()
		cl.SystemID = sql.Unqualify(qCLID)
		urlTempl := ""
		for _, system := range wh.ReviewSystems {
			if system.ID == cl.System {
				urlTempl = system.URLTemplate
				break
			}
		}
		cl.URL = strings.Replace(urlTempl, "%s", cl.SystemID, 1)
		rv = append(rv, cl)
	}

	pagination := httputils.ResponsePagination{
		Offset: offset,
		Size:   size,
		Total:  clstore.CountMany, // exact count not important for most day-to-day work.
	}
	return rv, pagination, nil
}

// A list of CI systems we support. So far, the mapping of task ID to link is project agnostic. If
// that stops being the case, then we'll need to supply this mapping on a per-instance basis.
var cisTemplates = map[string]string{
	"cirrus":               "https://cirrus-ci.com/task/%s",
	"buildbucket":          "https://cr-buildbucket.appspot.com/build/%s",
	"buildbucket-internal": "https://cr-buildbucket.appspot.com/build/%s",
}

// PatchsetsAndTryjobsForCL2 returns a summary of the data we have collected
// for a given Changelist, specifically any TryJobs that have uploaded data
// to Gold belonging to various patchsets in it.
func (wh *Handlers) PatchsetsAndTryjobsForCL2(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_PatchsetsAndTryjobsForCL2", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()
	if err := wh.cheapLimitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}
	clID, ok := mux.Vars(r)["id"]
	if !ok {
		http.Error(w, "Must specify 'id' of Changelist.", http.StatusBadRequest)
		return
	}
	crs, ok := mux.Vars(r)["system"]
	if !ok {
		http.Error(w, "Must specify 'system' of Changelist.", http.StatusBadRequest)
		return
	}
	rv, err := wh.getPatchsetsAndTryjobs(ctx, crs, clID)
	if err != nil {
		httputils.ReportError(w, err, "could not retrieve data for the specified CL.", http.StatusInternalServerError)
		return
	}
	sendJSONResponse(w, rv)
}

// getPatchsetsAndTryjobs returns a summary of the patchsets and tryjobs that belong to a given
// CL.
func (wh *Handlers) getPatchsetsAndTryjobs(ctx context.Context, crs, clID string) (frontend.ChangelistSummary, error) {
	ctx, span := trace.StartSpan(ctx, "getPatchsetsAndTryjobs")
	defer span.End()

	system, ok := wh.getCodeReviewSystem(crs)
	if !ok {
		return frontend.ChangelistSummary{}, skerr.Fmt("Invalid Code Review System %q", crs)
	}

	qCLID := sql.Qualify(crs, clID)
	row := wh.DB.QueryRow(ctx, `SELECT status, owner_email, subject, last_ingested_data FROM Changelists
WHERE changelist_id = $1`, qCLID)
	var cl frontend.Changelist
	if err := row.Scan(&cl.Status, &cl.Owner, &cl.Subject, &cl.Updated); err != nil {
		return frontend.ChangelistSummary{}, skerr.Wrapf(err, "checking if CL %q exists", qCLID)
	}
	cl.Updated = cl.Updated.UTC()
	cl.SystemID = clID
	cl.System = crs
	cl.URL = strings.Replace(system.URLTemplate, "%s", cl.SystemID, 1)
	rv := frontend.ChangelistSummary{CL: cl}

	const statement = `SELECT Patchsets.patchset_id, Patchsets.ps_order,
tryjob_id, display_name, Tryjobs.last_ingested_data, Tryjobs.system FROM
Tryjobs JOIN Patchsets ON Tryjobs.patchset_id = Patchsets.patchset_id
WHERE Tryjobs.changelist_id = $1
ORDER BY Patchsets.patchset_id
`
	rows, err := wh.DB.Query(ctx, statement, qCLID)
	if err != nil {
		return frontend.ChangelistSummary{}, skerr.Wrap(err)
	}
	defer rows.Close()
	var patchsets []*frontend.Patchset
	var currentPS *frontend.Patchset
	for rows.Next() {
		var psID string
		var order int
		var tj frontend.TryJob
		if err := rows.Scan(&psID, &order, &tj.SystemID, &tj.DisplayName, &tj.Updated, &tj.System); err != nil {
			return frontend.ChangelistSummary{}, skerr.Wrap(err)
		}
		tj.Updated = tj.Updated.UTC()
		urlTempl, ok := cisTemplates[tj.System]
		if !ok {
			return frontend.ChangelistSummary{}, skerr.Fmt("Unrecognized CIS system: %q", tj.System)
		}
		tj.URL = strings.Replace(urlTempl, "%s", sql.Unqualify(tj.SystemID), 1)
		if currentPS == nil || currentPS.SystemID != psID {
			currentPS = &frontend.Patchset{
				SystemID: psID,
				Order:    order,
			}
			patchsets = append(patchsets, currentPS)
		}
		currentPS.TryJobs = append(currentPS.TryJobs, tj)
	}

	rv.Patchsets = make([]frontend.Patchset, 0, len(patchsets)) // ensure non-nil slice
	for _, ps := range patchsets {
		rv.Patchsets = append(rv.Patchsets, *ps)
	}
	rv.NumTotalPatchsets = len(rv.Patchsets)

	sort.Slice(rv.Patchsets, func(i, j int) bool {
		return rv.Patchsets[i].Order > rv.Patchsets[j].Order
	})
	return rv, nil
}

// SearchHandler searches the data in the new SQL backend. It times out after 3 minutes, to prevent
// outstanding requests from growing unbounded.
func (wh *Handlers) SearchHandler(w http.ResponseWriter, r *http.Request) {
	if err := wh.limitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}

	q, ok := parseSearchQuery(w, r)
	if !ok {
		return
	}
	ctx, cancel := context.WithTimeout(r.Context(), 3*time.Minute)
	defer cancel()
	ctx, span := trace.StartSpan(ctx, "web_SearchHandler", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()

	searchResponse, err := wh.Search2API.Search(ctx, q)
	if err != nil {
		httputils.ReportError(w, err, "Search for digests failed in the SQL backend.", http.StatusInternalServerError)
		return
	}
	sendJSONResponse(w, searchResponse)
}

// parseSearchQuery extracts the search query from request.
func parseSearchQuery(w http.ResponseWriter, r *http.Request) (*search_query.Search, bool) {
	q := search_query.Search{Limit: 50}
	if err := search_query.ParseSearch(r, &q); err != nil {
		httputils.ReportError(w, err, "Search for digests failed.", http.StatusInternalServerError)
		return nil, false
	}
	// Currently, the frontend includes the corpus as a right trace value. That's really a no-op
	// because that info (and the test name) are specified in the grouping. As such, we delete
	// those so they don't cause us to go into a slow path accounting for keys when we do not
	// need to.
	// TODO(kjlubick) Make the frontend not supply these.
	delete(q.RightTraceValues, types.CorpusField)
	delete(q.RightTraceValues, types.PrimaryKeyField)
	return &q, true
}

// DetailsHandler returns the details about a single digest.
func (wh *Handlers) DetailsHandler(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_DetailsHandler", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()
	if err := wh.cheapLimitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}

	// Extract: test, digest, issue
	if err := r.ParseForm(); err != nil {
		httputils.ReportError(w, err, "Failed to parse form values", http.StatusInternalServerError)
		return
	}
	// TODO(kjlubick) require corpus
	test := r.Form.Get("test")
	digest := r.Form.Get("digest")
	if test == "" || !validation.IsValidDigest(digest) {
		http.Error(w, "Some query parameters are wrong or missing", http.StatusBadRequest)
		return
	}
	clID := r.Form.Get("changelist_id")
	crs := r.Form.Get("crs")
	if clID != "" {
		if _, ok := wh.getCodeReviewSystem(crs); !ok {
			http.Error(w, "Invalid Code Review System; did you include crs?", http.StatusBadRequest)
			return
		}
	} else {
		crs = ""
	}

	grouping, err := wh.getGroupingForTest(ctx, test)
	if err != nil {
		httputils.ReportError(w, err, "could not get grouping", http.StatusInternalServerError)
		return
	}
	ret, err := wh.Search2API.GetDigestDetails(ctx, grouping, types.Digest(digest), clID, crs)
	if err != nil {
		httputils.ReportError(w, err, "Unable to get digest details.", http.StatusInternalServerError)
		return
	}
	sendJSONResponse(w, ret)
}

// getGroupingForTest acts as a bridge for RPCs that only take in a test name, when they should
// be taking in a grouping. It looks up the grouping by test name and returns it.
// TODO(kjlubick) Migrate all RPCs and remove this function.
func (wh *Handlers) getGroupingForTest(ctx context.Context, testName string) (paramtools.Params, error) {
	ctx, span := trace.StartSpan(ctx, "getGroupingForTest")
	defer span.End()

	const statement = `SELECT keys FROM Groupings WHERE keys->'name' = $1 LIMIT 1`
	// Need to wrap testName with quotes to make it "valid JSON", so we can use the inverted index
	// on keys.
	row := wh.DB.QueryRow(ctx, statement, `"`+testName+`"`)
	var ps paramtools.Params
	if err := row.Scan(&ps); err != nil {
		return nil, skerr.Wrapf(err, "looking up grouping for test name %q", testName)
	}
	return ps, nil
}

// DiffHandler compares two digests and returns that information along with triage data.
func (wh *Handlers) DiffHandler(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_DiffHandler", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()

	// Extract: test, left, right where left and right are digests.
	if err := r.ParseForm(); err != nil {
		httputils.ReportError(w, err, "Failed to parse form values", http.StatusInternalServerError)
		return
	}
	// TODO(kjlubick) require corpus
	test := r.Form.Get("test")
	left := r.Form.Get("left")
	right := r.Form.Get("right")
	if test == "" || !validation.IsValidDigest(left) || !validation.IsValidDigest(right) {
		sklog.Debugf("Bad query params: %q %q %q", test, left, right)
		http.Error(w, "invalid query params", http.StatusBadRequest)
		return
	}
	clID := r.Form.Get("changelist_id")
	crs := r.Form.Get("crs")
	if clID != "" {
		if _, ok := wh.getCodeReviewSystem(crs); !ok {
			http.Error(w, "Invalid Code Review System; did you include crs?", http.StatusBadRequest)
			return
		}
	} else {
		crs = ""
	}

	grouping, err := wh.getGroupingForTest(ctx, test)
	if err != nil {
		httputils.ReportError(w, err, "could not get grouping", http.StatusInternalServerError)
		return
	}
	ret, err := wh.Search2API.GetDigestsDiff(ctx, grouping, types.Digest(left), types.Digest(right), clID, crs)
	if err != nil {
		httputils.ReportError(w, err, "Unable to get diff for digests.", http.StatusInternalServerError)
		return
	}
	sendJSONResponse(w, ret)
}

// ListIgnoreRules2 returns the current ignore rules in JSON format and the counts of
// how many traces they affect.
func (wh *Handlers) ListIgnoreRules2(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_ListIgnoreRules2", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()

	if err := wh.limitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}

	ignores, err := wh.getIgnores2(ctx)
	if err != nil {
		httputils.ReportError(w, err, "Failed to retrieve ignore rules, there may be none.", http.StatusInternalServerError)
		return
	}

	response := frontend.IgnoresResponse{
		Rules: ignores,
	}

	sendJSONResponse(w, response)
}

// getIgnores2 fetches all ignore rules and converts them into the frontend format. It will add the
// trace counts for each rule.
func (wh *Handlers) getIgnores2(ctx context.Context) ([]frontend.IgnoreRule, error) {
	ctx, span := trace.StartSpan(ctx, "getIgnores2")
	defer span.End()
	rules, err := wh.IgnoreStore.List(ctx)
	if err != nil {
		return nil, skerr.Wrapf(err, "fetching ignores from store")
	}

	ret := make([]frontend.IgnoreRule, 0, len(rules))
	for _, r := range rules {
		fr, err := frontend.ConvertIgnoreRule(r)
		if err != nil {
			return nil, skerr.Wrap(err)
		}
		ret = append(ret, fr)
	}
	// addIgnoreCounts updates the values of ret directly
	if err := wh.addIgnoreCounts2(ctx, ret); err != nil {
		return nil, skerr.Wrapf(err, "adding ignore counts to %d rules", len(ret))
	}
	return ret, nil
}

// addIgnoreCounts2 fetches all ignored traces from the SQL DB and then goes through all the ignore
// rules and figures out which rules applied to each of those traces. This allows us to count how
// many traces each rule affects and how many are exclusively impacted by a given rule.
func (wh *Handlers) addIgnoreCounts2(ctx context.Context, rules []frontend.IgnoreRule) error {
	ctx, span := trace.StartSpan(ctx, "addIgnoreCounts2")
	defer span.End()

	type counts struct {
		Count                   int
		UntriagedCount          int
		ExclusiveCount          int
		ExclusiveUntriagedCount int
	}

	ruleCounts := make([]counts, len(rules))
	wh.ignoredTracesCacheMutex.RLock()
	defer wh.ignoredTracesCacheMutex.RUnlock()
	for _, tr := range wh.ignoredTracesCache {
		idxMatched, untIdxMatched := -1, -1
		numMatched, untMatched := 0, 0
		for i, r := range rules {
			if paramtools.ParamSet(r.ParsedQuery).MatchesParams(tr.Keys) {
				numMatched++
				ruleCounts[i].Count++
				idxMatched = i

				// Check to see if the digest is untriaged at head
				if tr.Label == expectations.Untriaged {
					ruleCounts[i].UntriagedCount++
					untMatched++
					untIdxMatched = i
				}
			}
		}
		// Check for any exclusive matches
		if numMatched == 1 {
			ruleCounts[idxMatched].ExclusiveCount++
		}
		if untMatched == 1 {
			ruleCounts[untIdxMatched].ExclusiveUntriagedCount++
		}
	}
	for i := range rules {
		(&rules[i]).Count += ruleCounts[i].Count
		(&rules[i]).UntriagedCount += ruleCounts[i].UntriagedCount
		(&rules[i]).ExclusiveCount += ruleCounts[i].ExclusiveCount
		(&rules[i]).ExclusiveUntriagedCount += ruleCounts[i].ExclusiveUntriagedCount
	}
	return nil
}

// UpdateIgnoreRule updates an existing ignores rule.
func (wh *Handlers) UpdateIgnoreRule(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_UpdateIgnoreRule", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()
	user := wh.loggedInAs(r)
	if user == "" {
		http.Error(w, "You must be logged in to update an ignore rule.", http.StatusUnauthorized)
		return
	}
	id := mux.Vars(r)["id"]
	if id == "" {
		http.Error(w, "ID must be non-empty.", http.StatusBadRequest)
		return
	}
	expiresInterval, irb, err := getValidatedIgnoreRule(r)
	if err != nil {
		httputils.ReportError(w, err, "invalid ignore rule input", http.StatusBadRequest)
		return
	}
	ts := now.Now(ctx)
	ignoreRule := ignore.NewRule(user, ts.Add(expiresInterval), irb.Filter, irb.Note)
	ignoreRule.ID = id
	if err := wh.IgnoreStore.Update(ctx, ignoreRule); err != nil {
		httputils.ReportError(w, err, "Unable to update ignore rule", http.StatusInternalServerError)
		return
	}

	sklog.Infof("Successfully updated ignore with id %s", id)
	sendJSONResponse(w, map[string]string{"updated": "true"})
}

// getValidatedIgnoreRule parses the JSON from the given request into an IgnoreRuleBody. As a
// convenience, the duration as a time.Duration is returned.
func getValidatedIgnoreRule(r *http.Request) (time.Duration, frontend.IgnoreRuleBody, error) {
	irb := frontend.IgnoreRuleBody{}
	if err := parseJSON(r, &irb); err != nil {
		return 0, irb, skerr.Wrapf(err, "reading request JSON")
	}
	if irb.Filter == "" {
		return 0, irb, skerr.Fmt("must supply a filter")
	}
	// If a user accidentally includes a huge amount of text, we'd like to catch that here.
	if len(irb.Filter) >= 10*1024 {
		return 0, irb, skerr.Fmt("Filter must be < 10 KB")
	}
	if len(irb.Note) >= 1024 {
		return 0, irb, skerr.Fmt("Note must be < 1 KB")
	}
	d, err := human.ParseDuration(irb.Duration)
	if err != nil {
		return 0, irb, skerr.Wrapf(err, "invalid duration")
	}
	return d, irb, nil
}

// DeleteIgnoreRule deletes an existing ignores rule.
func (wh *Handlers) DeleteIgnoreRule(w http.ResponseWriter, r *http.Request) {
	user := wh.loggedInAs(r)
	if user == "" {
		http.Error(w, "You must be logged in to delete an ignore rule", http.StatusUnauthorized)
		return
	}
	ctx, span := trace.StartSpan(r.Context(), "web_DeleteIgnoreRule", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()
	id := mux.Vars(r)["id"]
	if id == "" {
		http.Error(w, "ID must be non-empty.", http.StatusBadRequest)
		return
	}

	if err := wh.IgnoreStore.Delete(ctx, id); err != nil {
		httputils.ReportError(w, err, "Unable to delete ignore rule", http.StatusInternalServerError)
		return
	}
	sklog.Infof("Successfully deleted ignore with id %s", id)
	sendJSONResponse(w, map[string]string{"deleted": "true"})
}

// AddIgnoreRule is for adding a new ignore rule.
func (wh *Handlers) AddIgnoreRule(w http.ResponseWriter, r *http.Request) {
	user := wh.loggedInAs(r)
	if user == "" {
		http.Error(w, "You must be logged in to add an ignore rule", http.StatusUnauthorized)
		return
	}
	ctx, span := trace.StartSpan(r.Context(), "web_AddIgnoreRule", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()

	expiresInterval, irb, err := getValidatedIgnoreRule(r)
	if err != nil {
		httputils.ReportError(w, err, "invalid ignore rule input", http.StatusBadRequest)
		return
	}
	ts := now.Now(ctx)
	ignoreRule := ignore.NewRule(user, ts.Add(expiresInterval), irb.Filter, irb.Note)
	if err := wh.IgnoreStore.Create(ctx, ignoreRule); err != nil {
		httputils.ReportError(w, err, "Failed to create ignore rule", http.StatusInternalServerError)
		return
	}

	sklog.Infof("Successfully added ignore from %s", user)
	sendJSONResponse(w, map[string]string{"added": "true"})
}

// TriageHandler handles a request to change the triage status of one or more
// digests of one test.
//
// It accepts a POST'd JSON serialization of TriageRequest and updates
// the expectations.
// TODO(kjlubick) In V3, this should take groupings, not test names. Additionally, to avoid race
//   conditions where users triage the same thing at the same time, the request should include
//   before and after. Finally, to avoid confusion on CLs, we should fail to apply changes
//   on closed CLs (skbug.com/12122)
func (wh *Handlers) TriageHandler(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_TriageHandler", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()
	user := login.LoggedInAs(r)
	if user == "" {
		http.Error(w, "You must be logged in to triage.", http.StatusUnauthorized)
		return
	}

	req := frontend.TriageRequest{}
	if err := parseJSON(r, &req); err != nil {
		httputils.ReportError(w, err, "Failed to parse JSON request.", http.StatusBadRequest)
		return
	}
	sklog.Infof("Triage v2 request: %#v", req)

	if err := wh.triage2(ctx, user, req); err != nil {
		httputils.ReportError(w, err, "Could not triage", http.StatusInternalServerError)
		return
	}
	// Nothing to return, so just set 200
	w.WriteHeader(http.StatusOK)
}

func (wh *Handlers) triage2(ctx context.Context, userID string, req frontend.TriageRequest) error {
	ctx, span := trace.StartSpan(ctx, "triage2")
	defer span.End()
	branch := ""
	if req.ChangelistID != "" && req.CodeReviewSystem != "" {
		branch = sql.Qualify(req.CodeReviewSystem, req.ChangelistID)
	}
	// If set, use the image matching algorithm's name as the author of this change.
	if req.ImageMatchingAlgorithm != "" {
		userID = req.ImageMatchingAlgorithm
	}

	deltas, err := wh.convertToDeltas(ctx, req)
	if err != nil {
		return skerr.Wrapf(err, "getting groupings")
	}
	if len(deltas) == 0 {
		return nil
	}
	span.AddAttributes(trace.Int64Attribute("num_changes", int64(len(deltas))))

	err = crdbpgx.ExecuteTx(ctx, wh.DB, pgx.TxOptions{}, func(tx pgx.Tx) error {
		newRecordID, err := writeRecord(ctx, tx, userID, len(deltas), branch)
		if err != nil {
			return err
		}
		err = fillPreviousLabel(ctx, tx, deltas, newRecordID)
		if err != nil {
			return err
		}
		err = writeDeltas(ctx, tx, deltas)
		if err != nil {
			return err
		}
		if branch == "" {
			return applyDeltasToPrimary(ctx, tx, deltas)
		}
		return applyDeltasToBranch(ctx, tx, deltas, branch)
	})
	if err != nil {
		return skerr.Wrapf(err, "writing %d expectations from %s to branch %q", len(deltas), userID, branch)
	}
	return nil
}

// convertToDeltas converts in triage request (a map) into a slice of deltas. These deltas are
// partially filled out, with only the
func (wh *Handlers) convertToDeltas(ctx context.Context, req frontend.TriageRequest) ([]schema.ExpectationDeltaRow, error) {
	rv := make([]schema.ExpectationDeltaRow, 0, len(req.TestDigestStatus))
	for test, digests := range req.TestDigestStatus {
		for d, label := range digests {
			if label == "" {
				// Empty string means the frontend didn't have a closest digest to use when making a
				// "bulk triage to the closest digest" request. It's easier to catch this on the
				// server side than make the JS check for empty string and mutate the POST body.
				continue
			}
			if !expectations.ValidLabel(label) {
				return nil, skerr.Fmt("invalid label %q in triage request", label)
			}
			labelAfter := schema.FromExpectationLabel(label)
			grouping, err := wh.getGroupingForTest(ctx, string(test))
			if err != nil {
				return nil, skerr.Wrap(err)
			}
			_, groupingID := sql.SerializeMap(grouping)
			digestBytes, err := sql.DigestToBytes(d)
			if err != nil {
				return nil, skerr.Wrap(err)
			}
			rv = append(rv, schema.ExpectationDeltaRow{
				GroupingID: groupingID,
				Digest:     digestBytes,
				LabelAfter: labelAfter,
			})
		}
	}
	return rv, nil
}

// fillPreviousLabel looks up all the expectations for the partially filled-out deltas passed in
// and updates those in-place. It only pulls labels from the primary branch, as this is not meant
// for long term use (see notes for getting to V3 triage).
func fillPreviousLabel(ctx context.Context, tx pgx.Tx, deltas []schema.ExpectationDeltaRow, newRecordID uuid.UUID) error {
	ctx, span := trace.StartSpan(ctx, "fillPreviousLabel")
	defer span.End()
	type expectationKey struct {
		groupingID schema.MD5Hash
		digest     schema.MD5Hash
	}
	toUpdate := map[expectationKey]*schema.ExpectationDeltaRow{}
	for i := range deltas {
		deltas[i].ExpectationRecordID = newRecordID
		deltas[i].LabelBefore = schema.LabelUntriaged
		toUpdate[expectationKey{
			groupingID: sql.AsMD5Hash(deltas[i].GroupingID),
			digest:     sql.AsMD5Hash(deltas[i].Digest),
		}] = &deltas[i]
	}

	statement := `SELECT grouping_id, digest, label FROM Expectations WHERE `
	// We should be safe from injection attacks because we are hex encoding known valid byte arrays.
	// I couldn't find a better way to match multiple composite keys using our usual techniques
	// involving placeholders.
	for i, d := range deltas {
		if i != 0 {
			statement += " OR "
		}
		statement += fmt.Sprintf(`(grouping_id = x'%x' AND digest = x'%x')`, d.GroupingID, d.Digest)
	}
	rows, err := tx.Query(ctx, statement)
	if err != nil {
		return err // don't wrap, could be retried
	}
	defer rows.Close()
	for rows.Next() {
		var gID schema.GroupingID
		var d schema.DigestBytes
		var label schema.ExpectationLabel
		if err := rows.Scan(&gID, &d, &label); err != nil {
			return skerr.Wrap(err) // probably not retryable
		}
		ek := expectationKey{
			groupingID: sql.AsMD5Hash(gID),
			digest:     sql.AsMD5Hash(d),
		}
		row := toUpdate[ek]
		if row == nil {
			sklog.Warningf("Unmatched row with grouping %x and digest %x", gID, d)
			continue // should never happen
		}
		row.LabelBefore = label
	}
	return nil
}

// StatusHandler returns information about the most recently ingested data and the triage status
// of the various corpora.
func (wh *Handlers) StatusHandler(w http.ResponseWriter, r *http.Request) {
	_, span := trace.StartSpan(r.Context(), "web_StatusHandler")
	defer span.End()
	wh.statusCacheMutex.RLock()
	defer wh.statusCacheMutex.RUnlock()
	// This should be an incredibly cheap call and therefore does not count against any quota.
	sendJSONResponse(w, wh.statusCache)
}

// ClusterDiffRequest contains the options that the frontend provides to the clusterdiff RPC.
type ClusterDiffRequest struct {
	Corpus                  string
	Filters                 paramtools.ParamSet
	IncludePositiveDigests  bool
	IncludeNegativeDigests  bool
	IncludeUntriagedDigests bool
	// TODO(kjlubick) the frontend does not yet support these yet.
	ChangelistID       string
	CodeReviewSystemID string
	PatchsetID         string
}

func parseClusterDiffQuery(r *http.Request) (ClusterDiffRequest, error) {
	if err := r.ParseForm(); err != nil {
		return ClusterDiffRequest{}, skerr.Wrap(err)
	}
	var rv ClusterDiffRequest
	// TODO(kjlubick) rename this field on the UI side
	if corpus := r.FormValue("source_type"); corpus == "" {
		return ClusterDiffRequest{}, skerr.Fmt("Must include corpus")
	} else {
		rv.Corpus = corpus
	}
	if q := r.FormValue("query"); q == "" {
		return ClusterDiffRequest{}, skerr.Fmt("Must include query")
	} else {
		filters, err := url.ParseQuery(q)
		if err != nil {
			return ClusterDiffRequest{}, skerr.Wrapf(err, "invalid query %q", q)
		}
		rv.Filters = paramtools.ParamSet(filters)
	}
	rv.IncludePositiveDigests = r.FormValue("pos") == "true"
	rv.IncludeNegativeDigests = r.FormValue("neg") == "true"
	rv.IncludeUntriagedDigests = r.FormValue("unt") == "true"

	rv.CodeReviewSystemID = r.FormValue("crs")
	rv.ChangelistID = r.FormValue("cl_id")
	rv.PatchsetID = r.FormValue("ps_id")
	return rv, nil
}

// ClusterDiffHandler computes the diffs between all digests that match the filters and
// returns them in a way that is convenient for rendering via d3.js
func (wh *Handlers) ClusterDiffHandler(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_ClusterDiffHandler", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()
	if err := wh.limitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}

	q, err := parseClusterDiffQuery(r)
	if err != nil {
		httputils.ReportError(w, err, "Invalid requrest", http.StatusBadRequest)
		return
	}

	testNames, ok := q.Filters[types.PrimaryKeyField]
	if !ok || len(testNames) == 0 {
		http.Error(w, "Must include test name", http.StatusBadRequest)
		return
	}
	leftGrouping := paramtools.Params{
		types.CorpusField:     q.Corpus,
		types.PrimaryKeyField: testNames[0],
	}
	delete(q.Filters, types.PrimaryKeyField)
	clusterOpts := search.ClusterOptions{
		Grouping:                leftGrouping,
		Filters:                 q.Filters,
		IncludePositiveDigests:  q.IncludePositiveDigests,
		IncludeNegativeDigests:  q.IncludeNegativeDigests,
		IncludeUntriagedDigests: q.IncludeUntriagedDigests,

		CodeReviewSystem: q.CodeReviewSystemID,
		ChangelistID:     q.ChangelistID,
		PatchsetID:       q.PatchsetID,
	}
	clusterResp, err := wh.Search2API.GetCluster(ctx, clusterOpts)
	if err != nil {
		httputils.ReportError(w, err, "Unable to compute cluster.", http.StatusInternalServerError)
		return
	}
	sendJSONResponse(w, clusterResp)
}

// ListTestsHandler returns all the tests in the given corpus and a count of how many digests
// have been seen for that.
func (wh *Handlers) ListTestsHandler(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_ListTestsHandler", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()
	if err := wh.limitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}
	// Inputs: (head, ignored, corpus, keys)
	q, err := frontend.ParseListTestsQuery(r)
	if err != nil {
		httputils.ReportError(w, err, "Failed to parse form data.", http.StatusBadRequest)
		return
	}

	counts, err := wh.Search2API.CountDigestsByTest(ctx, q)
	if err != nil {
		httputils.ReportError(w, err, "Could not compute query.", http.StatusInternalServerError)
		return
	}
	sendJSONResponse(w, counts)
}

// TriageLogHandler returns what has been triaged recently.
func (wh *Handlers) TriageLogHandler(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_TriageLogHandler", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()
	if err := wh.cheapLimitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}

	// Get the pagination params.
	q := r.URL.Query()
	offset, size, err := httputils.PaginationParams(q, 0, pageSize, maxPageSize)
	if err != nil {
		httputils.ReportError(w, err, "Invalid Pagination params", http.StatusBadRequest)
		return
	}

	clID := q.Get("changelist_id")
	crs := q.Get("crs")
	if clID != "" {
		if _, ok := wh.getCodeReviewSystem(crs); !ok {
			http.Error(w, "Invalid Code Review System; did you include crs?", http.StatusBadRequest)
			return
		}
	} else {
		crs = ""
	}

	logEntries, total, err := wh.getTriageLog2(ctx, crs, clID, offset, size)
	if err != nil {
		httputils.ReportError(w, err, "Unable to retrieve triage logs", http.StatusInternalServerError)
		return
	}

	response := frontend.TriageLogResponse2{
		Entries: logEntries,
		ResponsePagination: httputils.ResponsePagination{
			Offset: offset,
			Size:   size,
			Total:  total,
		},
	}

	sendJSONResponse(w, response)
}

// getTriageLog2 returns the specified entries and the total count of expectation records.
func (wh *Handlers) getTriageLog2(ctx context.Context, crs, clid string, offset, size int) ([]frontend.TriageLogEntry2, int, error) {
	ctx, span := trace.StartSpan(ctx, "getTriageLog2")
	defer span.End()

	total, err := wh.getTotalTriageRecords(ctx, crs, clid)
	if err != nil {
		return nil, 0, skerr.Wrap(err)
	}
	if total == 0 {
		return []frontend.TriageLogEntry2{}, 0, nil // We don't want null in our JSON response.
	}

	// Default to the primary branch, which is associated with branch_name (i.e. CL) as NULL.
	branchStatement := "WHERE branch_name IS NULL"
	if crs != "" {
		branchStatement = "WHERE branch_name = $3"
	}

	statement := `WITH
RecentRecords AS (
	SELECT expectation_record_id, user_name, triage_time
	FROM ExpectationRecords ` + branchStatement + `
	ORDER BY triage_time DESC, expectation_record_id
	OFFSET $1 LIMIT $2
)
SELECT RecentRecords.*, Groupings.keys, digest, label_before, label_after
FROM RecentRecords
	JOIN ExpectationDeltas ON RecentRecords.expectation_record_id = ExpectationDeltas.expectation_record_id
JOIN Groupings ON ExpectationDeltas.grouping_id = Groupings.grouping_id
ORDER BY triage_time DESC, expectation_record_id, digest
`
	args := []interface{}{offset, size}
	if crs != "" {
		args = append(args, sql.Qualify(crs, clid))
	}
	rows, err := wh.DB.Query(ctx, statement, args...)
	if err != nil {
		return nil, 0, skerr.Wrap(err)
	}
	defer rows.Close()
	var currentEntry *frontend.TriageLogEntry2
	var rv []frontend.TriageLogEntry2
	for rows.Next() {
		var record schema.ExpectationRecordRow
		var delta schema.ExpectationDeltaRow
		var grouping paramtools.Params
		if err := rows.Scan(&record.ExpectationRecordID, &record.UserName, &record.TriageTime,
			&grouping, &delta.Digest, &delta.LabelBefore, &delta.LabelAfter); err != nil {
			return nil, 0, skerr.Wrap(err)
		}
		if currentEntry == nil || currentEntry.ID != record.ExpectationRecordID.String() {
			rv = append(rv, frontend.TriageLogEntry2{
				ID:   record.ExpectationRecordID.String(),
				User: record.UserName,
				// Multiply by 1000 to convert seconds to milliseconds
				TS: record.TriageTime.UTC().Unix() * 1000,
			})
			currentEntry = &rv[len(rv)-1]
		}
		currentEntry.Details = append(currentEntry.Details, frontend.TriageDelta2{
			Grouping:    grouping,
			Digest:      types.Digest(hex.EncodeToString(delta.Digest)),
			LabelBefore: delta.LabelBefore.ToExpectation(),
			LabelAfter:  delta.LabelAfter.ToExpectation(),
		})
	}
	return rv, total, nil
}

// getTotalTriageRecords returns the total number of triage records for the CL (or the primary
// branch)
func (wh *Handlers) getTotalTriageRecords(ctx context.Context, crs, clid string) (int, error) {
	ctx, span := trace.StartSpan(ctx, "getTotalTriageRecords")
	defer span.End()

	branchStatement := "WHERE branch_name IS NULL"
	if crs != "" {
		branchStatement = "WHERE branch_name = $1"
	}

	statement := `SELECT COUNT(*) FROM ExpectationRecords ` + branchStatement
	var args []interface{}
	if crs != "" {
		args = append(args, sql.Qualify(crs, clid))
	}
	row := wh.DB.QueryRow(ctx, statement, args...)
	var count int
	if err := row.Scan(&count); err != nil {
		return 0, skerr.Wrap(err)
	}
	return count, nil
}

// TriageUndoHandler performs an "undo" for a given id. This id corresponds to the record id of the
// set of changes in the DB.
// If successful it returns the same result as a call to TriageLogHandler to reflect the changes.
func (wh *Handlers) TriageUndoHandler(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_TriageUndoHandler", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()
	// Get the user and make sure they are logged in.
	user := login.LoggedInAs(r)
	if user == "" {
		http.Error(w, "You must be logged in to change expectations", http.StatusUnauthorized)
		return
	}

	// Extract the id to undo.
	changeID := r.URL.Query().Get("id")

	// Do the undo procedure.
	if err := wh.undoExpectationChanges(ctx, changeID, user); err != nil {
		httputils.ReportError(w, err, "Unable to undo.", http.StatusInternalServerError)
		return
	}

	// Send the same response as a query for the first page.
	wh.TriageLogHandler(w, r)
}

// undoExpectationChanges will look up all ExpectationDeltas associated with the record that has
// the given ID. It will set the current expectations for those digests/groupings to be the
// label_before value. This will all be done in a transaction.
func (wh *Handlers) undoExpectationChanges(ctx context.Context, recordID, userID string) error {
	ctx, span := trace.StartSpan(ctx, "undoExpectationChanges")
	defer span.End()

	err := crdbpgx.ExecuteTx(ctx, wh.DB, pgx.TxOptions{}, func(tx pgx.Tx) error {
		deltas, err := getDeltasForRecord(ctx, tx, recordID)
		if err != nil {
			return err // Don't wrap - crdbpgx might retry
		}
		if len(deltas) == 0 {
			return skerr.Fmt("no expectation deltas found for record %s", recordID)
		}
		branchNameRow := tx.QueryRow(ctx, `SELECT branch_name FROM ExpectationRecords WHERE expectation_record_id = $1`, recordID)
		var branchOfOriginal pgtype.Text
		if err := branchNameRow.Scan(&branchOfOriginal); err != nil {
			return err
		}

		newRecordID, err := writeRecord(ctx, tx, userID, len(deltas), branchOfOriginal.String)
		if err != nil {
			return err
		}

		invertedDeltas := invertDeltas(deltas, newRecordID)
		if err := writeDeltas(ctx, tx, invertedDeltas); err != nil {
			return err
		}

		if branchOfOriginal.Status != pgtype.Present {
			err = applyDeltasToPrimary(ctx, tx, invertedDeltas)
		} else {
			err = applyDeltasToBranch(ctx, tx, invertedDeltas, branchOfOriginal.String)
		}
		return err
	})
	if err != nil {
		return skerr.Wrap(err)
	}
	return nil
}

// writeRecord writes a new ExpectationRecord to the DB.
func writeRecord(ctx context.Context, tx pgx.Tx, userID string, numChanges int, branch string) (uuid.UUID, error) {
	ctx, span := trace.StartSpan(ctx, "writeRecord")
	defer span.End()

	var br *string
	if branch != "" {
		br = &branch
	}
	const statement = `INSERT INTO ExpectationRecords
(user_name, triage_time, num_changes, branch_name) VALUES ($1, $2, $3, $4) RETURNING expectation_record_id`
	row := tx.QueryRow(ctx, statement, userID, now.Now(ctx), numChanges, br)
	var recordUUID uuid.UUID
	err := row.Scan(&recordUUID)
	if err != nil {
		return uuid.UUID{}, err
	}
	return recordUUID, nil
}

// invertDeltas returns a slice of deltas corresponding to the same grouping+digest pairs as the
// original slice, but with inverted before/after labels and a new record ID.
func invertDeltas(deltas []schema.ExpectationDeltaRow, newRecordID uuid.UUID) []schema.ExpectationDeltaRow {
	var rv []schema.ExpectationDeltaRow
	for _, d := range deltas {
		rv = append(rv, schema.ExpectationDeltaRow{
			ExpectationRecordID: newRecordID,
			GroupingID:          d.GroupingID,
			Digest:              d.Digest,
			LabelBefore:         d.LabelAfter, // Intentionally flipped around
			LabelAfter:          d.LabelBefore,
		})
	}
	return rv
}

// getDeltasForRecord returns all ExpectationDeltaRows for the given record ID.
func getDeltasForRecord(ctx context.Context, tx pgx.Tx, recordID string) ([]schema.ExpectationDeltaRow, error) {
	ctx, span := trace.StartSpan(ctx, "getDeltasForRecord")
	defer span.End()
	const statement = `SELECT grouping_id, digest, label_before, label_after
FROM ExpectationDeltas WHERE expectation_record_id = $1`
	rows, err := tx.Query(ctx, statement, recordID)
	if err != nil {
		return nil, err // Don't wrap - crdbpgx might retry
	}
	defer rows.Close()
	var deltas []schema.ExpectationDeltaRow
	for rows.Next() {
		var row schema.ExpectationDeltaRow
		if err := rows.Scan(&row.GroupingID, &row.Digest, &row.LabelBefore, &row.LabelAfter); err != nil {
			return nil, skerr.Wrap(err) // probably not retriable
		}
		deltas = append(deltas, row)
	}
	return deltas, nil
}

// writeDeltas writes the given rows to the SQL DB.
func writeDeltas(ctx context.Context, tx pgx.Tx, deltas []schema.ExpectationDeltaRow) error {
	ctx, span := trace.StartSpan(ctx, "writeDeltas")
	defer span.End()

	const statement = `INSERT INTO ExpectationDeltas
(expectation_record_id, grouping_id, digest, label_before, label_after) VALUES `
	const valuesPerRow = 5
	vp := sql.ValuesPlaceholders(valuesPerRow, len(deltas))
	arguments := make([]interface{}, 0, len(deltas)*valuesPerRow)
	for _, d := range deltas {
		arguments = append(arguments, d.ExpectationRecordID, d.GroupingID, d.Digest, d.LabelBefore, d.LabelAfter)
	}
	_, err := tx.Exec(ctx, statement+vp, arguments...)
	return err // don't wrap, could be retryable
}

// applyDeltasToPrimary applies the given deltas to the primary branch expectations.
func applyDeltasToPrimary(ctx context.Context, tx pgx.Tx, deltas []schema.ExpectationDeltaRow) error {
	ctx, span := trace.StartSpan(ctx, "applyDeltasToPrimary")
	defer span.End()

	const statement = `UPSERT INTO Expectations
(grouping_id, digest, label, expectation_record_id) VALUES `
	const valuesPerRow = 4
	vp := sql.ValuesPlaceholders(valuesPerRow, len(deltas))
	arguments := make([]interface{}, 0, len(deltas)*valuesPerRow)
	for _, d := range deltas {
		arguments = append(arguments, d.GroupingID, d.Digest, d.LabelAfter, d.ExpectationRecordID)
	}
	_, err := tx.Exec(ctx, statement+vp, arguments...)
	return err // don't wrap, could be retryable
}

// applyDeltasToBranch applies the given deltas to the given branch (i.e. CL).
func applyDeltasToBranch(ctx context.Context, tx pgx.Tx, deltas []schema.ExpectationDeltaRow, branch string) error {
	ctx, span := trace.StartSpan(ctx, "applyInvertedDeltasToBranch")
	defer span.End()

	const statement = `UPSERT INTO SecondaryBranchExpectations
(branch_name, grouping_id, digest, label, expectation_record_id) VALUES `
	const valuesPerRow = 5
	vp := sql.ValuesPlaceholders(valuesPerRow, len(deltas))
	arguments := make([]interface{}, 0, len(deltas)*valuesPerRow)
	for _, d := range deltas {
		arguments = append(arguments, branch, d.GroupingID, d.Digest, d.LabelAfter, d.ExpectationRecordID)
	}
	_, err := tx.Exec(ctx, statement+vp, arguments...)
	return err // don't wrap, could be retryable
}

// ParamsHandler returns all Params that could be searched over. It uses the SQL Backend and
// returns *only* the keys, not the options.
func (wh *Handlers) ParamsHandler(w http.ResponseWriter, r *http.Request) {
	if err := wh.cheapLimitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}
	ctx, span := trace.StartSpan(r.Context(), "web_ParamsHandler", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()

	if err := r.ParseForm(); err != nil {
		httputils.ReportError(w, err, "Invalid form headers", http.StatusBadRequest)
		return
	}
	clID := r.Form.Get("changelist_id")
	crs := r.Form.Get("crs")

	if clID == "" {
		ps, err := wh.Search2API.GetPrimaryBranchParamset(ctx)
		if err != nil {
			httputils.ReportError(w, err, "Could not get paramset for primary branch", http.StatusInternalServerError)
			return
		}
		sendJSONResponse(w, ps)
		return
	}

	if _, ok := wh.getCodeReviewSystem(crs); !ok {
		http.Error(w, "Invalid Code Review System; did you include crs?", http.StatusBadRequest)
		return
	}
	ps, err := wh.Search2API.GetChangelistParamset(ctx, crs, clID)
	if err != nil {
		httputils.ReportError(w, err, "Could not get paramset for given CL", http.StatusInternalServerError)
		return
	}
	sendJSONResponse(w, ps)
}

// CommitsHandler returns the last n commits with data that make up the sliding window.
func (wh *Handlers) CommitsHandler(w http.ResponseWriter, r *http.Request) {
	if err := wh.cheapLimitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}
	ctx, span := trace.StartSpan(r.Context(), "web_CommitsHandler", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()

	commits, err := wh.Search2API.GetCommitsInWindow(ctx)
	if err != nil {
		httputils.ReportError(w, err, "Could not get commits", http.StatusInternalServerError)
		return
	}
	sendJSONResponse(w, commits)
}

// KnownHashesHandler returns known hashes that have been written to GCS in the background
// Each line contains a single digest for an image. Bots will then only upload images which
// have a hash not found on this list, avoiding significant amounts of unnecessary uploads.
func (wh *Handlers) KnownHashesHandler(w http.ResponseWriter, r *http.Request) {
	// No limit for anon users - this is an endpoint backed up by baseline servers, and
	// should be able to handle a large load.
	_, span := trace.StartSpan(r.Context(), "web_TextKnownHashesProxy")
	defer span.End()
	w.Header().Set("Content-Type", "text/plain")
	wh.knownHashesMutex.RLock()
	defer wh.knownHashesMutex.RUnlock()
	if _, err := w.Write([]byte(wh.knownHashesCache)); err != nil {
		sklog.Errorf("Failed to write the known hashes", err)
		return
	}
}

// BaselineHandlerV2 returns a JSON representation of that baseline including
// baselines for a options issue. It can respond to requests like these:
//
//    /json/expectations
//    /json/expectations?issue=123456
//
// The "issue" parameter indicates the changelist ID for which we would like to
// retrieve the baseline. In that case the returned options will be a blend of
// the master baseline and the baseline defined for the changelist (usually
// based on tryjob results).
func (wh *Handlers) BaselineHandlerV2(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "frontend_BaselineHandlerV2")
	defer span.End()
	// No limit for anon users - this is an endpoint backed up by baseline servers, and
	// should be able to handle a large load.

	q := r.URL.Query()
	clID := q.Get("issue")
	crs := q.Get("crs")

	if clID != "" {
		if _, ok := wh.getCodeReviewSystem(crs); !ok {
			http.Error(w, "Invalid CRS provided.", http.StatusBadRequest)
			return
		}
	} else {
		crs = ""
	}

	bl, err := wh.fetchBaseline(ctx, crs, clID)
	if err != nil {
		httputils.ReportError(w, err, "Fetching baseline failed.", http.StatusInternalServerError)
		return
	}

	sendJSONResponse(w, bl)
}

// fetchBaseline returns an object that contains all the positive and negatively triaged digests
// for either the primary branch or the primary branch and the CL. As per usual, the triage status
// on a CL overrides the triage status on the primary branch.
func (wh *Handlers) fetchBaseline(ctx context.Context, crs, clID string) (frontend.BaselineV2Response, error) {
	ctx, span := trace.StartSpan(ctx, "fetchBaseline")
	defer span.End()

	statement := `WITH
PrimaryBranchExps AS (
	SELECT grouping_id, digest, label FROM Expectations
	WHERE label = 'n' OR label = 'p'
)`
	var args []interface{}
	if crs == "" {
		span.AddAttributes(trace.StringAttribute("type", "primary"))
		statement += `
SELECT Groupings.keys ->> 'name', encode(digest, 'hex'), label FROM PrimaryBranchExps
JOIN Groupings ON PrimaryBranchExps.grouping_id = Groupings.grouping_id`
	} else {
		span.AddAttributes(trace.StringAttribute("type", "changelist"))
		qCLID := sql.Qualify(crs, clID)
		statement += `,
CLExps AS (
	SELECT grouping_id, digest, label FROM SecondaryBranchExpectations
	WHERE branch_name = $1
),
JoinedExps AS (
	SELECT COALESCE(CLExps.grouping_id, PrimaryBranchExps.grouping_id) as grouping_id,
		COALESCE(CLExps.digest, PrimaryBranchExps.digest) as digest,
		COALESCE(CLExps.label, PrimaryBranchExps.label, 'u') as label
    FROM CLExps FULL OUTER JOIN PrimaryBranchExps ON
		CLExps.grouping_id = PrimaryBranchExps.grouping_id
		AND CLExps.digest = PrimaryBranchExps.digest
)
SELECT Groupings.keys ->> 'name', encode(digest, 'hex'), label FROM JoinedExps
JOIN Groupings ON JoinedExps.grouping_id = Groupings.grouping_id
WHERE label = 'n' OR label = 'p'`
		args = append(args, qCLID)
	}
	rows, err := wh.DB.Query(ctx, statement, args...)
	if err != nil {
		return frontend.BaselineV2Response{}, skerr.Wrap(err)
	}
	defer rows.Close()
	baseline := expectations.Baseline{}
	for rows.Next() {
		var testName types.TestName
		var digest types.Digest
		var label schema.ExpectationLabel
		if err := rows.Scan(&testName, &digest, &label); err != nil {
			return frontend.BaselineV2Response{}, skerr.Wrap(err)
		}
		byDigest, ok := baseline[testName]
		if !ok {
			byDigest = map[types.Digest]expectations.Label{}
			baseline[testName] = byDigest
		}
		byDigest[digest] = label.ToExpectation()
	}

	return frontend.BaselineV2Response{
		CodeReviewSystem: crs,
		ChangelistID:     clID,
		Expectations:     baseline,
	}, nil
}

// DigestListHandler returns a list of digests for a given test. This is used by goldctl's
// local diff tech.
func (wh *Handlers) DigestListHandler(w http.ResponseWriter, r *http.Request) {
	if err := wh.cheapLimitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}
	ctx, span := trace.StartSpan(r.Context(), "web_DigestListHandler")
	defer span.End()

	if err := r.ParseForm(); err != nil {
		httputils.ReportError(w, err, "Failed to parse form values", http.StatusInternalServerError)
		return
	}

	encodedGrouping := r.Form.Get("grouping")
	if encodedGrouping == "" {
		http.Error(w, "You must include 'grouping'", http.StatusBadRequest)
		return
	}
	groupingSet, err := url.ParseQuery(encodedGrouping)
	if err != nil {
		httputils.ReportError(w, skerr.Wrapf(err, "bad grouping %s", encodedGrouping), "Invalid grouping", http.StatusBadRequest)
		return
	}
	grouping := make(paramtools.Params, len(groupingSet))
	for key, values := range groupingSet {
		if len(values) == 0 {
			continue
		}
		grouping[key] = values[0]
	}

	// If needed, we could add a TTL cache here.
	out, err := wh.Search2API.GetDigestsForGrouping(ctx, grouping)
	if err != nil {
		httputils.ReportError(w, err, "Could not retrieve digests", http.StatusInternalServerError)
		return
	}
	sendJSONResponse(w, out)
}

// Whoami returns the email address of the user or service account used to authenticate the
// request. For debugging purposes only.
func (wh *Handlers) Whoami(w http.ResponseWriter, r *http.Request) {
	if err := wh.cheapLimitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}
	_, span := trace.StartSpan(r.Context(), "web_Whoami")
	defer span.End()

	user := wh.loggedInAs(r)
	sendJSONResponse(w, map[string]string{"whoami": user})
}

// LatestPositiveDigestHandler returns the most recent positive digest for the given trace.
// Starting at the tip of tree, it will skip over any missing data, untriaged digests or digests
// triaged negative until it finds a positive digest.
func (wh *Handlers) LatestPositiveDigestHandler(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_LatestPositiveDigestHandler")
	defer span.End()
	if err := wh.cheapLimitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}

	tID, ok := mux.Vars(r)["traceID"]
	if !ok {
		http.Error(w, "Must specify traceID.", http.StatusBadRequest)
		return
	}
	traceID, err := hex.DecodeString(tID)
	if err != nil {
		httputils.ReportError(w, err, "Invalid traceID - must be an MD5 hash", http.StatusBadRequest)
		return
	}
	digest, err := wh.getLatestPositiveDigest(ctx, traceID)
	if err != nil {
		httputils.ReportError(w, err, "Could not complete query.", http.StatusInternalServerError)
		return
	}
	sendJSONResponse(w, frontend.MostRecentPositiveDigestResponse{Digest: digest})
}

func (wh *Handlers) getLatestPositiveDigest(ctx context.Context, traceID schema.TraceID) (types.Digest, error) {
	ctx, span := trace.StartSpan(ctx, "getLatestPositiveDigest")
	defer span.End()

	const statement = `WITH
RecentDigests AS (
	SELECT digest, commit_id, grouping_id FROM TraceValues WHERE trace_id = $1
	ORDER BY commit_id DESC LIMIT 1000 -- arbitrary limit
)
SELECT encode(RecentDigests.digest, 'hex') FROM RecentDigests
JOIN Expectations ON Expectations.grouping_id = RecentDigests.grouping_id AND
	Expectations.digest = RecentDigests.digest
WHERE label = 'p'
ORDER BY commit_id DESC LIMIT 1
`
	row := wh.DB.QueryRow(ctx, statement, traceID)
	var digest types.Digest
	if err := row.Scan(&digest); err != nil {
		if err == pgx.ErrNoRows {
			return "", nil
		}
		return "", skerr.Wrap(err)
	}
	return digest, nil
}

// ChangelistSearchRedirect redirects the user to a search page showing the search results
// for a given CL. It will do a (hopefully) quick scan of the untriaged digests - if it finds some,
// it will include the corpus containing some of those untriaged digests in the search query so the
// user will see results (instead of getting directed to a corpus with no results).
func (wh *Handlers) ChangelistSearchRedirect(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_ChangelistSearchRedirect")
	defer span.End()
	if err := wh.cheapLimitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
	}

	requestVars := mux.Vars(r)
	crs, ok := requestVars["system"]
	if !ok {
		http.Error(w, "Must specify 'system' of Changelist.", http.StatusBadRequest)
		return
	}
	clID, ok := requestVars["id"]
	if !ok {
		http.Error(w, "Must specify 'id' of Changelist.", http.StatusBadRequest)
		return
	}
	_, ok = wh.getCodeReviewSystem(crs)
	if !ok {
		http.Error(w, "Invalid Code Review System", http.StatusBadRequest)
		return
	}
	// This allows users to link to something like:
	// https://gold.skia.org/cl/gerrit/3213712&master=true
	// And the page loads showing the all the results.
	extraQueryParam := ""
	if strings.Contains(clID, "?") {
		s := strings.Split(clID, "?")
		clID, extraQueryParam = s[0], s[1]
	} else if strings.Contains(clID, "&") {
		s := strings.Split(clID, "&")
		clID, extraQueryParam = s[0], s[1]
	}

	qualifiedPSID, psOrder, err := wh.getLatestPatchset(ctx, crs, clID)
	if err != nil {
		httputils.ReportError(w, err, "Could not find latest patchset", http.StatusNotFound)
		return
	}
	// TODO(kjlubick) when we change the patchsets arg to not be a list of orders, we should
	//   update it here too (probably specify the ps id).
	baseURL := fmt.Sprintf("/search?issue=%s&crs=%s&patchsets=%d", clID, crs, psOrder)
	if extraQueryParam != "" {
		baseURL += "&" + extraQueryParam
	}

	corporaWithUntriagedUnignoredDigests, err := wh.getActionableDigests(ctx, crs, clID, qualifiedPSID)
	if err != nil {
		sklog.Errorf("Error getting digests for CL %s from CRS %s with PS %s: %s", clID, crs, qualifiedPSID, err)
		http.Redirect(w, r, baseURL, http.StatusTemporaryRedirect)
		return
	}
	if len(corporaWithUntriagedUnignoredDigests) == 0 {
		http.Redirect(w, r, baseURL, http.StatusTemporaryRedirect)
		return
	}
	http.Redirect(w, r, baseURL+"&corpus="+corporaWithUntriagedUnignoredDigests[0].Corpus, http.StatusTemporaryRedirect)
}

// getLatestPatchset returns the latest patchset for a given CL. It goes off of created_ts, due
// to the fact that (for GitHub) rebases can happen and potentially cause ps_order to be off.
func (wh *Handlers) getLatestPatchset(ctx context.Context, crs, clID string) (string, int, error) {
	ctx, span := trace.StartSpan(ctx, "getLatestPatchset")
	defer span.End()
	const statement = `SELECT patchset_id, ps_order FROM Patchsets
WHERE changelist_id = $1
ORDER BY created_ts DESC, ps_order DESC
LIMIT 1`
	row := wh.DB.QueryRow(ctx, statement, sql.Qualify(crs, clID))
	var qualifiedID string
	var order int
	if err := row.Scan(&qualifiedID, &order); err != nil {
		return "", 0, skerr.Wrap(err)
	}
	return qualifiedID, order, nil
}

type corpusAndCount struct {
	Corpus string
	Count  int
}

// getActionableDigests returns a list of corpus and the number of untriaged, not-ignored digests
// that have been seen in the data for the given PS. We choose *not* to strip out digests that
// are already on the primary branch because that additional join makes this query too slow.
// As is, it can take 3-4 seconds on a large instance like Skia. The return value will be sorted
// by count, with the corpus name being the tie-breaker.
func (wh *Handlers) getActionableDigests(ctx context.Context, crs, clID, qPSID string) ([]corpusAndCount, error) {
	ctx, span := trace.StartSpan(ctx, "getActionableDigests")
	defer span.End()

	const statement = `WITH
DataFromCL AS (
    SELECT secondary_branch_trace_id, SecondaryBranchValues.grouping_id, digest
    FROM SecondaryBranchValues WHERE branch_name = $1 AND version_name = $2
),
ExpectationsForCL AS (
    SELECT grouping_id, digest, label
    FROM SecondaryBranchExpectations
    WHERE branch_name = $1
),
JoinedExpectations AS (
    SELECT COALESCE(ExpectationsForCL.grouping_id, Expectations.grouping_id) AS grouping_id,
        COALESCE(ExpectationsForCL.digest, Expectations.digest) AS digest,
        COALESCE(ExpectationsForCL.label, Expectations.label, 'u') AS label
    FROM ExpectationsForCL FULL OUTER JOIN Expectations ON
    ExpectationsForCL.grouping_id = Expectations.grouping_id
        AND ExpectationsForCL.digest = Expectations.digest
),
UntriagedData AS (
    SELECT secondary_branch_trace_id, DataFromCL.grouping_id, DataFromCL.digest FROM DataFromCL
    LEFT JOIN JoinedExpectations ON DataFromCL.grouping_id = JoinedExpectations.grouping_id
        AND DataFromCL.digest = JoinedExpectations.digest
    WHERE label = 'u' OR label IS NULL
),
UnignoredUntriagedData AS (
    SELECT DISTINCT UntriagedData.grouping_id, digest FROM UntriagedData
    JOIN Traces ON UntriagedData.secondary_branch_trace_id = Traces.trace_id
    AND matches_any_ignore_rule = FALSE
)
SELECT keys->>'source_type', COUNT(*) FROM Groupings JOIN UnignoredUntriagedData
    ON Groupings.grouping_id = UnignoredUntriagedData.grouping_id
GROUP BY 1
ORDER BY 2 DESC, 1 ASC`

	rows, err := wh.DB.Query(ctx, statement, sql.Qualify(crs, clID), qPSID)
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	defer rows.Close()
	var rv []corpusAndCount
	for rows.Next() {
		var c corpusAndCount
		if err := rows.Scan(&c.Corpus, &c.Count); err != nil {
			return nil, skerr.Wrap(err)
		}
		rv = append(rv, c)
	}
	return rv, nil
}

func (wh *Handlers) loggedInAs(r *http.Request) string {
	if wh.testingAuthAs != "" {
		return wh.testingAuthAs
	}
	return login.LoggedInAs(r)
}

func (wh *Handlers) getCodeReviewSystem(crs string) (clstore.ReviewSystem, bool) {
	var system clstore.ReviewSystem
	found := false
	for _, rs := range wh.ReviewSystems {
		if rs.ID == crs {
			system = rs
			found = true
		}
	}
	return system, found
}

const (
	validDigestLength = 2 * md5.Size
	dotPNG            = ".png"
)

// ImageHandler returns either a single image or a diff between two images identified by their
// respective digests.
func (wh *Handlers) ImageHandler(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_ImageHandler")
	defer span.End()
	// No rate limit, as this should be quite fast.
	_, imgFile := path.Split(r.URL.Path)
	// Get the file that was requested and verify that it's a valid PNG file.
	if !strings.HasSuffix(imgFile, dotPNG) {
		noCacheNotFound(w)
		return
	}

	// Trim the image extension to get the image or diff ID.
	imgID := imgFile[:len(imgFile)-len(dotPNG)]
	// Cache images for 12 hours.
	w.Header().Set("Cache-Control", "public, max-age=43200")
	if len(imgID) == validDigestLength {
		// Example request:
		// https://skia-infra-gold.skia.org/img/images/8588cad6f3821b948468df35b67778ef.png
		wh.serveImageWithDigest(ctx, w, types.Digest(imgID))
	} else if len(imgID) == validDigestLength*2+1 {
		// Example request:
		// https://skia-infra-gold.skia.org/img/diffs/81c4d3a64cf32143ff6c1fbf4cbbec2d-d20731492287002a3f046eae4bd4ce7d.png
		left := types.Digest(imgID[:validDigestLength])
		// + 1 for the dash
		right := types.Digest(imgID[validDigestLength+1:])
		wh.serveImageDiff(ctx, w, left, right)
	} else {
		noCacheNotFound(w)
		return
	}
}

// serveImageWithDigest downloads the image from GCS and returns it. If there is an error, a 404
// or 500 error is returned, as appropriate.
func (wh *Handlers) serveImageWithDigest(ctx context.Context, w http.ResponseWriter, digest types.Digest) {
	ctx, span := trace.StartSpan(ctx, "serveImageWithDigest")
	defer span.End()
	// Go's image package has no color profile support and we convert to 8-bit NRGBA to diff,
	// but our source images may have embedded color profiles and be up to 16-bit. So we must
	// at least take care to serve the original .pngs unaltered.
	b, err := wh.GCSClient.GetImage(ctx, digest)
	if err != nil {
		sklog.Warningf("Could not get image with digest %s: %s", digest, err)
		noCacheNotFound(w)
		return
	}
	if _, err := w.Write(b); err != nil {
		httputils.ReportError(w, err, "Could not load image. Try again later.", http.StatusInternalServerError)
		return
	}
}

// serveImageDiff downloads the left and right images, computes the diff between them, encodes
// the diff as a PNG image and writes it to the provided ResponseWriter. If there is an error, it
// returns a 404 or 500 error as appropriate.
func (wh *Handlers) serveImageDiff(ctx context.Context, w http.ResponseWriter, left types.Digest, right types.Digest) {
	ctx, span := trace.StartSpan(ctx, "serveImageDiff")
	defer span.End()
	// TODO(lovisolo): Diff in NRGBA64?
	// TODO(lovisolo): Make sure each pair of images is in the same color space before diffing?
	//                 (They probably are today but it'd be a good correctness check to make sure.)
	eg, eCtx := errgroup.WithContext(ctx)
	var leftImg *image.NRGBA
	var rightImg *image.NRGBA
	eg.Go(func() error {
		b, err := wh.GCSClient.GetImage(eCtx, left)
		if err != nil {
			return skerr.Wrap(err)
		}
		leftImg, err = decode(b)
		return skerr.Wrap(err)
	})
	eg.Go(func() error {
		b, err := wh.GCSClient.GetImage(eCtx, right)
		if err != nil {
			return skerr.Wrap(err)
		}
		rightImg, err = decode(b)
		return skerr.Wrap(err)
	})
	if err := eg.Wait(); err != nil {
		sklog.Warningf("Could not get diff for images %q and %q: %s", left, right, err)
		noCacheNotFound(w)
		return
	}
	// Compute the diff image.
	_, diffImg := diff.PixelDiff(leftImg, rightImg)

	// Write output image to the http.ResponseWriter. Content-Type is set automatically
	// based on the first 512 bytes of written data. See docs for ResponseWriter.Write()
	// for details.
	//
	// The encoding step below does not take color profiles into account. This is fine since
	// both the left and right images used to compute the diff are in the same color space,
	// and also because the resulting diff image is just a visual approximation of the
	// differences between the left and right images.
	if err := encodeImg(w, diffImg); err != nil {
		httputils.ReportError(w, err, "could not serve diff image", http.StatusInternalServerError)
		return
	}
}

// decode decodes the provided bytes as a PNG and returns them as an *image.NRGBA.
func decode(b []byte) (*image.NRGBA, error) {
	im, err := png.Decode(bytes.NewReader(b))
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	return diff.GetNRGBA(im), nil
}

// noCacheNotFound disables caching and returns a 404.
func noCacheNotFound(w http.ResponseWriter) {
	w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
	http.NotFound(w, nil)
}

// ChangelistSummaryHandler returns a summary of the new and untriaged digests produced by this
// CL across all Patchsets.
func (wh *Handlers) ChangelistSummaryHandler(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_ChangelistSummaryHandler", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()
	if err := wh.cheapLimitForGerritPlugin(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}
	clID, ok := mux.Vars(r)["id"]
	if !ok {
		http.Error(w, "Must specify 'id' of Changelist.", http.StatusBadRequest)
		return
	}
	crs, ok := mux.Vars(r)["system"]
	if !ok {
		http.Error(w, "Must specify 'system' of Changelist.", http.StatusBadRequest)
		return
	}
	system, ok := wh.getCodeReviewSystem(crs)
	if !ok {
		http.Error(w, "Invalid Code Review System", http.StatusBadRequest)
		return
	}

	qCLID := sql.Qualify(system.ID, clID)
	sum, err := wh.getCLSummary2(ctx, qCLID)
	if err != nil {
		httputils.ReportError(w, err, "Could not get summary", http.StatusInternalServerError)
		return
	}
	rv := convertChangelistSummaryResponseV1(sum)
	sendJSONResponse(w, rv)
}

// getCLSummary2 fetches, caches, and returns the summary for a given CL. If the result has already
// been cached, it will return that cached value with a flag if the value is still up to date or
// not. If the cached data is stale, it will spawn a goroutine to update the cached value.
func (wh *Handlers) getCLSummary2(ctx context.Context, qCLID string) (search.NewAndUntriagedSummary, error) {
	ts, err := wh.Search2API.ChangelistLastUpdated(ctx, qCLID)
	if err != nil {
		return search.NewAndUntriagedSummary{}, skerr.Wrap(err)
	}
	if ts.IsZero() { // A Zero time means we have no data for this CL.
		return search.NewAndUntriagedSummary{}, nil
	}

	cached, ok := wh.clSummaryCache.Get(qCLID)
	if ok {
		sum, ok := cached.(search.NewAndUntriagedSummary)
		if ok {
			if ts.Before(sum.LastUpdated) || sum.LastUpdated.Equal(ts) {
				sum.Outdated = false
				return sum, nil
			}
			// Result is stale. Start a goroutine to fetch it again.
			done := make(chan struct{})
			go func() {
				// We intentionally use context.Background() and not the request's context because
				// if we return a result, we want the fetching in the background to continue so
				// if/when the client tries again, we can serve that updated result.
				ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
				defer cancel()
				newValue, err := wh.Search2API.NewAndUntriagedSummaryForCL(ctx, qCLID)
				if err != nil {
					sklog.Warningf("Could not fetch out of date summary for cl %s in background: %s", qCLID, err)
					return
				}
				wh.clSummaryCache.Add(qCLID, newValue)
				done <- struct{}{}
			}()
			// Wait up to 500ms to return the latest value quickly if available
			timer := time.NewTimer(500 * time.Millisecond)
			defer timer.Stop()
			select {
			case <-done:
			case <-timer.C:
			}
			cached, ok = wh.clSummaryCache.Get(qCLID)
			if ok {
				if possiblyUpdated, ok := cached.(search.NewAndUntriagedSummary); ok {
					if ts.Before(possiblyUpdated.LastUpdated) || possiblyUpdated.LastUpdated.Equal(ts) {
						// We were able to fetch new data quickly, so return it now.
						possiblyUpdated.Outdated = false
						return possiblyUpdated, nil
					}
				}
			}
			// The cached data is still stale or invalid, so return what we have marked as outdated.
			sum.Outdated = true
			return sum, nil
		}
	}
	// Invalid or missing cache entry. We must fetch because we have nothing to give the user.
	sum, err := wh.Search2API.NewAndUntriagedSummaryForCL(ctx, qCLID)
	if err != nil {
		return search.NewAndUntriagedSummary{}, skerr.Wrap(err)
	}
	wh.clSummaryCache.Add(qCLID, sum)
	return sum, nil
}

// convertChangelistSummaryResponseV1 converts the search2 version of a Changelist summary into
// the version expected by the frontend.
func convertChangelistSummaryResponseV1(summary search.NewAndUntriagedSummary) frontend.ChangelistSummaryResponseV1 {
	xps := make([]frontend.PatchsetNewAndUntriagedSummaryV1, 0, len(summary.PatchsetSummaries))
	for _, ps := range summary.PatchsetSummaries {
		xps = append(xps, frontend.PatchsetNewAndUntriagedSummaryV1{
			NewImages:            ps.NewImages,
			NewUntriagedImages:   ps.NewUntriagedImages,
			TotalUntriagedImages: ps.TotalUntriagedImages,
			PatchsetID:           ps.PatchsetID,
			PatchsetOrder:        ps.PatchsetOrder,
		})
	}
	// It is convenient for the UI to have these sorted with the latest patchset first.
	sort.Slice(xps, func(i, j int) bool {
		return xps[i].PatchsetOrder > xps[j].PatchsetOrder
	})
	return frontend.ChangelistSummaryResponseV1{
		ChangelistID:      summary.ChangelistID,
		PatchsetSummaries: xps,
		Outdated:          summary.Outdated,
	}
}

// StartCacheWarming starts warming the caches for data we want to serve quickly. It starts
// goroutines that will run in the background (until the provided context is cancelled).
func (wh *Handlers) StartCacheWarming(ctx context.Context) {
	wh.startCLCacheProcess(ctx)
	wh.startStatusCacheProcess(ctx)
	wh.startIgnoredTraceCacheProcess(ctx)
	wh.StartKnownHashesCacheProcess(ctx)
}

// startCLCacheProcess starts a go routine to warm the CL Summary cache. This way, most
// summaries are responsive, even on big instances.
func (wh *Handlers) startCLCacheProcess(ctx context.Context) {
	// We warm every CL that was open and produced data or saw triage activity in the last 5 days.
	// After the first cycle, we will incrementally update the cache.
	lastCheck := now.Now(ctx).Add(-5 * 24 * time.Hour)
	go util.RepeatCtx(ctx, time.Minute, func(ctx context.Context) {
		ctx, span := trace.StartSpan(ctx, "web_warmCLCacheCycle", trace.WithSampler(trace.AlwaysSample()))
		defer span.End()
		newTS := now.Now(ctx)
		rows, err := wh.DB.Query(ctx, `WITH
ChangelistsWithNewData AS (
	SELECT changelist_id FROM Changelists
	WHERE status = 'open' and last_ingested_data > $1
),
ChangelistsWithTriageActivity AS (
	SELECT DISTINCT branch_name AS changelist_id FROM ExpectationRecords
	WHERE branch_name IS NOT NULL AND triage_time > $1
)
SELECT changelist_id FROM ChangelistsWithNewData
UNION
SELECT changelist_id FROM ChangelistsWithTriageActivity
`, lastCheck)
		if err != nil {
			if err == pgx.ErrNoRows {
				sklog.Infof("No CLS updated since %s", lastCheck)
				lastCheck = newTS
				return
			}
			sklog.Errorf("Could not fetch updated CLs to warm cache: %s", err)
			return
		}
		defer rows.Close()
		var qualifiedIDS []string
		for rows.Next() {
			var qID string
			if err := rows.Scan(&qID); err != nil {
				sklog.Errorf("Could not scan: %s", err)
			}
			qualifiedIDS = append(qualifiedIDS, qID)
		}
		sklog.Infof("Warming cache for %d CLs", len(qualifiedIDS))
		span.AddAttributes(trace.Int64Attribute("num_cls", int64(len(qualifiedIDS))))
		// warm cache 3 at a time. This number of goroutines was chosen arbitrarily.
		_ = util.ChunkIterParallel(ctx, len(qualifiedIDS), len(qualifiedIDS)/3+1, func(ctx context.Context, startIdx int, endIdx int) error {
			if err := ctx.Err(); err != nil {
				return nil
			}
			for _, qCLID := range qualifiedIDS[startIdx:endIdx] {
				_, err := wh.getCLSummary2(ctx, qCLID)
				if err != nil {
					sklog.Warningf("Ignoring error while warming CL Cache for %s: %s", qCLID, err)
				}
			}
			return nil
		})
		lastCheck = newTS
		sklog.Infof("Done warming cache")
	})
}

// startStatusCacheProcess will compute the GUI Status on a timer and save it to the cache.
func (wh *Handlers) startStatusCacheProcess(ctx context.Context) {
	go util.RepeatCtx(ctx, time.Minute, func(ctx context.Context) {
		ctx, span := trace.StartSpan(ctx, "web_warmStatusCacheCycle", trace.WithSampler(trace.AlwaysSample()))
		defer span.End()

		gs, err := wh.Search2API.ComputeGUIStatus(ctx)
		if err != nil {
			sklog.Errorf("Could not compute GUI Status: %s", err)
			return
		}

		wh.statusCacheMutex.Lock()
		defer wh.statusCacheMutex.Unlock()
		wh.statusCache = gs
	})
}

// StartKnownHashesCacheProcess will fetch the known hashes on a timer and save it to the cache.
func (wh *Handlers) StartKnownHashesCacheProcess(ctx context.Context) {
	go util.RepeatCtx(ctx, time.Minute, func(ctx context.Context) {
		ctx, span := trace.StartSpan(ctx, "web_warmKnownHashesCacheCycle", trace.WithSampler(trace.AlwaysSample()))
		defer span.End()

		var buf bytes.Buffer
		if err := wh.GCSClient.LoadKnownDigests(ctx, &buf); err != nil {
			sklog.Errorf("Could not fetch known digests: %s", err)
			return
		}

		wh.knownHashesMutex.Lock()
		defer wh.knownHashesMutex.Unlock()
		wh.knownHashesCache = buf.String()
	})
}

type ignoredTrace struct {
	Keys  paramtools.Params
	Label expectations.Label
}

//startIgnoredTraceCacheProcess will periodically update the cache of ignored traces.
func (wh *Handlers) startIgnoredTraceCacheProcess(ctx context.Context) {
	go util.RepeatCtx(ctx, time.Minute, func(ctx context.Context) {
		ctx, span := trace.StartSpan(ctx, "web_warmIgnoredTraceCacheCycle", trace.WithSampler(trace.AlwaysSample()))
		defer span.End()

		if err := wh.updateIgnoredTracesCache(ctx); err != nil {
			sklog.Errorf("Could not get all ignored traces: %s", err)
		}
	})
}

// updateIgnoredTracesCache fetches all ignored traces that have recent data and returns both
// the trace keys and the triage status of the digest at ToT.
func (wh *Handlers) updateIgnoredTracesCache(ctx context.Context) error {
	ctx, span := trace.StartSpan(ctx, "updateIgnoredTracesCache")
	defer span.End()

	const statement = `WITH
RecentCommits AS (
	SELECT commit_id FROM CommitsWithData
	ORDER BY commit_id DESC LIMIT $1
),
OldestCommitInWindow AS (
	SELECT commit_id FROM RecentCommits
	ORDER BY commit_id ASC LIMIT 1
)
SELECT keys, label FROM ValuesAtHead
JOIN OldestCommitInWindow ON ValuesAtHead.most_recent_commit_id >= OldestCommitInWindow.commit_id
	AND matches_any_ignore_rule = TRUE
JOIN Expectations ON ValuesAtHead.grouping_id = Expectations.grouping_id
	AND ValuesAtHead.digest = Expectations.digest
`

	rows, err := wh.DB.Query(ctx, statement, wh.WindowSize)
	if err != nil {
		return skerr.Wrap(err)
	}
	defer rows.Close()

	var ignoredTraces []ignoredTrace
	for rows.Next() {
		var ps paramtools.Params
		var label schema.ExpectationLabel
		if err := rows.Scan(&ps, &label); err != nil {
			return skerr.Wrap(err)
		}
		ignoredTraces = append(ignoredTraces, ignoredTrace{
			Keys:  ps,
			Label: label.ToExpectation(),
		})
	}

	wh.ignoredTracesCacheMutex.Lock()
	defer wh.ignoredTracesCacheMutex.Unlock()
	wh.ignoredTracesCache = ignoredTraces
	return nil
}

// PositiveDigestsByGroupingIDHandler returns all positively triaged digests seen in the sliding
// window for a given grouping, split up by trace.
// Used by https://source.chromium.org/chromium/chromium/src/+/main:content/test/gpu/gold_inexact_matching/base_parameter_optimizer.py
func (wh *Handlers) PositiveDigestsByGroupingIDHandler(w http.ResponseWriter, r *http.Request) {
	ctx, span := trace.StartSpan(r.Context(), "web_PositiveDigestsByGroupingIDHandler", trace.WithSampler(trace.AlwaysSample()))
	defer span.End()
	if err := wh.cheapLimitForAnonUsers(r); err != nil {
		httputils.ReportError(w, err, "Try again later", http.StatusInternalServerError)
		return
	}

	gID := mux.Vars(r)["groupingID"]
	if len(gID) != 2*md5.Size {
		http.Error(w, "Must specify 'groupingID', which is a hex-encoded MD5 hash of the JSON encoded group keys (e.g. source_type and name)", http.StatusBadRequest)
		return
	}
	groupingID, err := hex.DecodeString(gID)
	if err != nil {
		httputils.ReportError(w, err, "Invalid 'groupingID', which is a hex-encoded MD5 hash of the JSON encoded group keys (e.g. source_type and name)", http.StatusBadRequest)
		return
	}

	groupingKeys, err := wh.lookupGrouping(ctx, groupingID)
	if err != nil {
		httputils.ReportError(w, err, "Unknown groupingID", http.StatusBadRequest)
		return
	}

	beginTile, endTile, err := wh.getTilesInWindow(ctx)
	if err != nil {
		httputils.ReportError(w, err, "Error while finding commits with data", http.StatusInternalServerError)
		return
	}

	resp, err := wh.getPositiveDigests(ctx, beginTile, endTile, groupingID)
	if err != nil {
		httputils.ReportError(w, err, "Error while finding positive traces for grouping", http.StatusInternalServerError)
		return
	}
	resp.GroupingID = gID
	resp.GroupingKeys = groupingKeys

	sendJSONResponse(w, resp)
}

// lookupGrouping returns the keys associated with the provided grouping id.
func (wh *Handlers) lookupGrouping(ctx context.Context, id schema.GroupingID) (paramtools.Params, error) {
	ctx, span := trace.StartSpan(ctx, "lookupGrouping")
	defer span.End()

	row := wh.DB.QueryRow(ctx, `SELECT keys FROM Groupings WHERE grouping_id = $1`, id)
	var keys paramtools.Params
	err := row.Scan(&keys)
	if err != nil {
		return nil, skerr.Wrap(err) // likely the grouping was not found
	}
	return keys, nil
}

// getTilesInWindow returns the start and end tile of the given window.
func (wh *Handlers) getTilesInWindow(ctx context.Context) (schema.TileID, schema.TileID, error) {
	ctx, span := trace.StartSpan(ctx, "getTilesInWindow")
	defer span.End()
	const statement = `WITH
RecentCommits AS (
	SELECT tile_id, commit_id FROM CommitsWithData
	AS OF SYSTEM TIME '-0.1s'
	ORDER BY commit_id DESC LIMIT $1
)
SELECT MIN(tile_id), MAX(tile_id) FROM RecentCommits
AS OF SYSTEM TIME '-0.1s'
`
	row := wh.DB.QueryRow(ctx, statement, wh.WindowSize)
	var lc pgtype.Int4
	var mc pgtype.Int4
	if err := row.Scan(&lc, &mc); err != nil {
		if err == pgx.ErrNoRows {
			return 0, 0, nil // not enough commits seen, so start at tile 0.
		}
		return 0, 0, skerr.Wrapf(err, "getting latest commit")
	}
	if lc.Status == pgtype.Null || mc.Status == pgtype.Null {
		// There are no commits with data, so start at tile 0.
		return 0, 0, nil
	}
	return schema.TileID(lc.Int), schema.TileID(mc.Int), nil
}

// getPositiveDigests returns all digests which are triaged as positive in the given tiles that
// belong to the provided grouping. These digests are split according to the traces that made them.
func (wh *Handlers) getPositiveDigests(ctx context.Context, beginTile, endTile schema.TileID, groupingID schema.GroupingID) (frontend.PositiveDigestsByGroupingIDResponse, error) {
	ctx, span := trace.StartSpan(ctx, "getPositiveDigests")
	defer span.End()

	tracesForGroup, err := wh.getTracesForGroup(ctx, groupingID)
	if err != nil {
		return frontend.PositiveDigestsByGroupingIDResponse{}, skerr.Wrap(err)
	}

	tilesInRange := make([]schema.TileID, 0, endTile-beginTile+1)
	for i := beginTile; i <= endTile; i++ {
		tilesInRange = append(tilesInRange, i)
	}
	// Querying traces, and then digests is much faster because the indexes can be used more
	// efficiently. kjlubick@ tried specifying INNER LOOKUP JOIN but that didn't work on v20.2.7
	const statement = `
WITH
DigestsOfInterest AS (
    SELECT DISTINCT digest, trace_id FROM TiledTraceDigests
    WHERE tile_id = ANY($1) AND trace_id = ANY($2)
)
SELECT encode(DigestsOfInterest.trace_id, 'hex'), encode(DigestsOfInterest.digest, 'hex') FROM DigestsOfInterest
JOIN Expectations ON grouping_id = $3 AND label = 'p' AND
  Expectations.digest = DigestsOfInterest.digest
ORDER BY 1, 2`

	rows, err := wh.DB.Query(ctx, statement, tilesInRange, tracesForGroup, groupingID)
	if err != nil {
		return frontend.PositiveDigestsByGroupingIDResponse{}, skerr.Wrapf(err, "fetching digests")
	}
	defer rows.Close()
	traceToDigests := make(map[string][]types.Digest, len(tracesForGroup))
	for rows.Next() {
		var d types.Digest
		var t string
		if err := rows.Scan(&t, &d); err != nil {
			return frontend.PositiveDigestsByGroupingIDResponse{}, skerr.Wrap(err)
		}
		traceToDigests[t] = append(traceToDigests[t], d)
	}

	rv := frontend.PositiveDigestsByGroupingIDResponse{}
	for traceID, digests := range traceToDigests {
		rv.Traces = append(rv.Traces, frontend.PositiveDigestsTraceInfo{
			TraceID:         traceID,
			PositiveDigests: digests,
		})
	}
	// Sort by trace ID for determinism - the digests should already be sorted
	// because of the SQL query.
	sort.Slice(rv.Traces, func(i, j int) bool {
		return rv.Traces[i].TraceID < rv.Traces[j].TraceID
	})
	return rv, nil
}

// getTracesForGroup returns all the traces that are a part of the specified grouping.
func (wh *Handlers) getTracesForGroup(ctx context.Context, id schema.GroupingID) ([]schema.TraceID, error) {
	ctx, span := trace.StartSpan(ctx, "getTracesForGroup")
	defer span.End()
	const statement = `SELECT trace_id FROM Traces
AS OF SYSTEM TIME '-0.1s'
WHERE grouping_id = $1`
	rows, err := wh.DB.Query(ctx, statement, id)
	if err != nil {
		return nil, skerr.Wrapf(err, "fetching trace ids")
	}
	defer rows.Close()
	var rv []schema.TraceID
	for rows.Next() {
		var t schema.TraceID
		if err := rows.Scan(&t); err != nil {
			return nil, skerr.Wrap(err)
		}
		rv = append(rv, t)
	}
	return rv, nil
}
