package analysis

import (
	"encoding/json"
	"sort"
	"sync"
	"time"

	"github.com/rcrowley/go-metrics"
	"github.com/skia-dev/glog"

	"go.skia.org/infra/go/timer"
	"go.skia.org/infra/go/util"
	"go.skia.org/infra/golden/go/expstorage"
	"go.skia.org/infra/golden/go/filediffstore"
	"go.skia.org/infra/golden/go/ignore"
	"go.skia.org/infra/golden/go/storage"
	"go.skia.org/infra/golden/go/types"
	ptypes "go.skia.org/infra/perf/go/types"
)

const (
	NEW_TILE_CACHE_KEY     = "newtile"
	IGNORED_TILE_CACHE_KEY = "ignoredtile"
)

var (
	// The number of times we've successfully loaded and processed a tile.
	runsCounter metrics.Counter

	// The number of times an error has ocurred when trying to load a tile.
	errorTileLoadingCounter metrics.Counter
)

func init() {
	runsCounter = metrics.NewRegisteredCounter("analysis.runs", metrics.DefaultRegistry)
	errorTileLoadingCounter = metrics.NewRegisteredCounter("analysis.errors", metrics.DefaultRegistry)
}

type PathToURLConverter func(string) string

// LabeledTrace stores a Trace with labels and digests. CommitIds, Digests and
// Labels are of the same length, identical indices refer to the same digest.
type LabeledTrace struct {
	Params      map[string]string
	CommitIds   []int
	Digests     []string
	Labels      []types.Label
	Id          int
	IgnoreRules []*ignore.IgnoreRule
}

func NewLabeledTrace(params map[string]string, capacity int, traceId int) *LabeledTrace {
	return &LabeledTrace{
		Params:      params,
		CommitIds:   make([]int, 0, capacity),
		Digests:     make([]string, 0, capacity),
		Labels:      make([]types.Label, 0, capacity),
		Id:          traceId,
		IgnoreRules: []*ignore.IgnoreRule{},
	}
}

// addLabledDigests adds the given tripples of commitIds, digests and labels to this LabeledTrace.
func (lt *LabeledTrace) addLabeledDigests(commitIds []int, digests []string, labels []types.Label) {
	lt.CommitIds = append(lt.CommitIds, commitIds...)
	lt.Digests = append(lt.Digests, digests...)
	lt.Labels = append(lt.Labels, labels...)
}

// addIgnoreRules attaches the ignore rules that match his trace.
func (lt *LabeledTrace) addIgnoreRules(newRules []*ignore.IgnoreRule) {
	lt.IgnoreRules = append(lt.IgnoreRules, newRules...)
}

// LabeledTile aggregates the traces of a tile and provides a slice of commits
// that the commitIds in LabeledTrace refer to.
// LabeledTile and LabeledTrace store the cannonical information
// extracted from the unterlying tile store. The (redundant) output data is
// derived from these.
type LabeledTile struct {
	Commits []*ptypes.Commit

	// Traces are indexed by the primary key (test name). This is somewhat
	// redundant, but this also output format.
	Traces map[string][]*LabeledTrace

	// CommitsByDigest maps a corpus and a digest to a list of commit ids.
	// i.e. CommitsByDigest[corpus][digest] -> slice with indices of Commits.
	CommitsByDigest map[string]map[string][]int

	// Keeps track of unique ids for traces within this tile.
	TraceIdCounter int
}

func NewLabeledTile() *LabeledTile {
	return &LabeledTile{
		Commits:         []*ptypes.Commit{},
		CommitsByDigest: map[string]map[string][]int{},
		Traces:          map[string][]*LabeledTrace{},
		TraceIdCounter:  0,
	}
}

// getLabeledTrace is a utility function that returns the testName and a labeled
// trace for the given trace (read from a TileStore). If the LabeledTrace does
// not exist it will be added.
func (t *LabeledTile) getLabeledTrace(trace ptypes.Trace) (string, *LabeledTrace) {
	params := trace.Params()
	pKey := params[types.PRIMARY_KEY_FIELD]
	if _, ok := t.Traces[pKey]; !ok {
		// Add the primary key with a single labled trace.
		t.Traces[pKey] = []*LabeledTrace{}
	}

	// Search through the traces associated witht this test.
	for _, v := range t.Traces[pKey] {
		if util.MapsEqual(v.Params, params) {
			return pKey, v
		}
	}

	// If we cannot find the trace in our set of tests we are adding a new
	// labeled trace.
	newLT := NewLabeledTrace(params, trace.Len(), t.TraceIdCounter)
	t.TraceIdCounter++
	t.Traces[pKey] = append(t.Traces[pKey], newLT)
	return pKey, newLT
}

// LabelCounts is an output type to hold counts for classification labels.
type LabelCounts struct {
	Unt []int `json:"unt"` // Untriaged
	Pos []int `json:"pos"` // Positive
	Neg []int `json:"neg"` // Negative
}

func newLabelCounts(length int) *LabelCounts {
	return &LabelCounts{
		Unt: make([]int, length),
		Pos: make([]int, length),
		Neg: make([]int, length),
	}
}

// AnalyzeState captures the state of a partition of the incoming data.
// When a tile is read from disk it is partitioned into two tiles: current
// and ignored. current contains everything we want to be able to review
// continuously and ignored contains all ignored traces.
// This struct is the container for one of these partitions and the derived
// information.
type AnalyzeState struct {
	// Canonical data structure to hold our information about commits, digests
	// and labels.
	Tile *LabeledTile

	// Index to query the Tile.
	Index *LabeledTileIndex

	// Output data structures that are derived from Tile.
	TestDetails *GUITestDetails
	Status      *GUIStatus
	BlameLists  *GUIBlameLists
}

// Analyzer continuously manages tasks like polling for new traces
// on disk and generating diffs between images. It is the primary interface
// to be called by the HTTP frontend.
type Analyzer struct {
	storages *storage.Storage

	// current contains the state of the digests we are primariliy interested in.
	current *AnalyzeState

	// ignored contains the state of ignored digests.
	ignored *AnalyzeState

	// lastRawTile points to the last tile loaded from the tileStore.
	lastRawTile *ptypes.Tile

	// labeledTileCache caches the labeled tiles extracted tiles.
	labeledTileCache util.LRUCache

	// converter supplied by the client of the type to convert a path to a URL
	pathToURLConverter PathToURLConverter

	// Lock to protect the expectations and current* variables.
	mutex sync.RWMutex

	// Counts the number of times the main event loop has executed.
	// This is for testing only.
	loopCounter int
}

type LabeledTileCodec int

func (d LabeledTileCodec) Encode(v interface{}) ([]byte, error) {
	return json.Marshal(v)
}

func (d LabeledTileCodec) Decode(data []byte) (interface{}, error) {
	var v LabeledTile
	err := json.Unmarshal(data, &v)
	return &v, err
}

func NewAnalyzer(storages *storage.Storage, puConverter PathToURLConverter, cacheFactory filediffstore.CacheFactory, timeBetweenPolls time.Duration) *Analyzer {
	labeledTileCache := cacheFactory("ti", LabeledTileCodec(0))

	result := &Analyzer{
		storages:           storages,
		pathToURLConverter: puConverter,

		current:          &AnalyzeState{},
		ignored:          &AnalyzeState{},
		lastRawTile:      nil,
		labeledTileCache: labeledTileCache,
	}

	go result.loop(timeBetweenPolls)
	return result
}

// ListTestDetails returns a list of triage details based on the supplied
// query. It's complementary to GetTestDetails which returns a single test
// detail.
// TODO(stephana): This should provide pagination since the list is potentially
// very long. If we don't add pagination, this should be merged with
// GetTestDetail.
func (a *Analyzer) ListTestDetails(query map[string][]string) (*GUITestDetails, error) {
	a.mutex.RLock()
	defer a.mutex.RUnlock()

	if len(query) == 0 {
		return a.current.TestDetails, nil
	}

	effectiveQuery := make(map[string][]string, len(query))
	foundUntriaged := a.getUntriagedTestDetails(query, effectiveQuery, true)
	tests := make([]*GUITestDetail, 0, len(foundUntriaged))

	for testName, untriaged := range foundUntriaged {
		testDetail := a.current.TestDetails.lookup(testName)
		tests = append(tests, &GUITestDetail{
			Name:      testName,
			Untriaged: untriaged,
			Positive:  testDetail.Positive,
			Negative:  testDetail.Negative,
		})
	}

	// Sort the test details.
	sort.Sort(GUITestDetailSortable(tests))

	return &GUITestDetails{
		Commits:   a.current.TestDetails.Commits,
		AllParams: a.current.Index.getAllParams(query),
		Query:     effectiveQuery,
		Tests:     tests,
		Blames:    a.current.BlameLists.Blames,
	}, nil
}

// GetTestDetails returns the untriaged, positive and negative digests for a
// specific test with the necessary information (diff metrics, image urls) to
// assign a label to the untriaged digests.
// If query is not empty then we will return traces that match the query.
// If the query is empty and testName is not empty we will return the
// traces of the corresponding test.If both query and testName are empty
// we will return all traces.
// TODO (stephana): If the result is too big we should add pagination.
func (a *Analyzer) GetTestDetails(testName string, query map[string][]string) (*GUITestDetails, error) {
	a.mutex.RLock()
	defer a.mutex.RUnlock()

	var effectiveQuery map[string][]string
	testDetail := a.current.TestDetails.lookup(testName)
	untriaged := testDetail.Untriaged
	if len(query) > 0 {
		effectiveQuery = map[string][]string{}

		// Filter by only this test.
		query[types.PRIMARY_KEY_FIELD] = []string{testName}
		foundUntriaged := a.getUntriagedTestDetails(query, effectiveQuery, false)
		delete(effectiveQuery, types.PRIMARY_KEY_FIELD)

		// Only consider the result if some query parameters were valid.
		if len(effectiveQuery) > 0 {
			if temp, ok := foundUntriaged[testName]; ok {
				untriaged = temp
			} else {
				untriaged = map[string]*GUIUntriagedDigest{}
			}
		}
	}

	return &GUITestDetails{
		Commits:         a.current.TestDetails.Commits,
		CommitsByDigest: map[string]map[string][]int{testName: a.current.TestDetails.CommitsByDigest[testName]},
		AllParams:       a.current.Index.getAllParams(query),
		Query:           effectiveQuery,
		Blames:          map[string][]*BlameDistribution{testName: a.current.BlameLists.Blames[testName]},
		Tests: []*GUITestDetail{
			&GUITestDetail{
				Name:      testName,
				Untriaged: untriaged,
				Positive:  testDetail.Positive,
				Negative:  testDetail.Negative,
			},
		},
	}, nil
}

// SetDigestLabels sets the labels for the given digest and records the user
// that made the classification.
func (a *Analyzer) SetDigestLabels(labeledTestDigests map[string]types.TestClassification, userId string) (*GUITestDetails, error) {
	a.mutex.Lock()
	defer a.mutex.Unlock()

	if err := a.storages.ExpectationsStore.AddChange(labeledTestDigests, userId); err != nil {
		return nil, err
	}

	expectations, err := a.storages.ExpectationsStore.Get()
	if err != nil {
		return nil, err
	}

	// Let's update our knowledge of the labels.
	a.updateDerivedOutputs(labeledTestDigests, expectations, a.current)
	a.updateDerivedOutputs(labeledTestDigests, expectations, a.ignored)

	result := make([]*GUITestDetail, 0, len(labeledTestDigests))
	for testName := range labeledTestDigests {
		result = append(result, a.current.TestDetails.lookup(testName))
	}

	return &GUITestDetails{
		Commits:   a.current.TestDetails.Commits,
		AllParams: a.current.Index.getAllParams(nil),
		Tests:     result,
	}, nil
}

func (a *Analyzer) GetStatus() *GUIStatus {
	return a.current.Status
}

// ListIgnoreRules returns all current ignore rules.
func (a *Analyzer) ListIgnoreRules() ([]*ignore.IgnoreRule, error) {
	rules, err := a.storages.IgnoreStore.List()
	if err != nil {
		return nil, err
	}

	// TODO(stephana): Inject Count and other statistics about the
	// ignored traces. This will be based on LabeledTrace.IgnoreRules.

	return rules, nil
}

// AddIgnoreRule adds a new ignore rule and recalculates the new state of the
// system.
func (a *Analyzer) AddIgnoreRule(ignoreRule *ignore.IgnoreRule) error {
	if err := a.storages.IgnoreStore.Create(ignoreRule); err != nil {
		return err
	}

	a.processTile(false, false)

	return nil
}

// UpdateIgnoreRule updates an existing ignore rule and recalculates the new state of the
// system.
func (a *Analyzer) UpdateIgnoreRule(ruleId int, ignoreRule *ignore.IgnoreRule) error {
	if err := a.storages.IgnoreStore.Update(ruleId, ignoreRule); err != nil {
		return err
	}

	a.processTile(false, false)

	return nil
}

// DeleteIgnoreRule deletes the ignore rule and recalculates the state of the
// system.
func (a *Analyzer) DeleteIgnoreRule(ruleId int, user string) error {
	count, err := a.storages.IgnoreStore.Delete(ruleId, user)
	if err != nil {
		return err
	}

	if count > 0 {
		a.processTile(false, false)
	}

	return nil
}

// GetBlameList returns the blame lists for the test identified by testName or
// nil if there is no such test.
func (a *Analyzer) GetBlameList(testName string) *GUIBlameLists {
	ret, ok := a.current.BlameLists.Blames[testName]
	if !ok {
		return nil
	}

	return &GUIBlameLists{
		Commits: a.current.BlameLists.Commits,
		Blames:  map[string][]*BlameDistribution{testName: ret},
	}
}

// loop is the main event loop.
func (a *Analyzer) loop(timeBetweenPolls time.Duration) {
	// Process the tile with caching. If the result is false that means
	// no tile was loaded from disk and we need to do another run with
	// the latest tile.
	if !a.processTile(true, true) {
		a.processTile(false, true)
	}
	for _ = range time.Tick(timeBetweenPolls) {
		a.processTile(false, true)
	}
}

// getCachedTiles returns the last instances of current and ignored.
func (a *Analyzer) getCachedTiles() (*LabeledTile, *LabeledTile) {
	if newLabeledTile, ok := a.labeledTileCache.Get(NEW_TILE_CACHE_KEY); ok {
		if ignoredLabeledTile, ok := a.labeledTileCache.Get(IGNORED_TILE_CACHE_KEY); ok {
			return newLabeledTile.(*LabeledTile), ignoredLabeledTile.(*LabeledTile)
		}
	}
	return nil, nil
}

// cacheTiles stores the latest instances of current and ignored.
func (a *Analyzer) cacheTiles(newLabeledTile *LabeledTile, ignoredLabeledTile *LabeledTile) {
	a.labeledTileCache.Add(NEW_TILE_CACHE_KEY, newLabeledTile)
	a.labeledTileCache.Add(IGNORED_TILE_CACHE_KEY, ignoredLabeledTile)
}

// processTile loads a tile (built by the ingest process) and partitions it
// into two labeled tiles one with the traces of interest and the traces we
// are ignoring.
// The flags indicate whether to use the cached labeled tiles (during startup)
// and whether to reload the tile from disk or use lastRawTile instead.
// The return value indicates whether a raw tile was loaded from disk.
func (a *Analyzer) processTile(useCached bool, reloadRawTile bool) bool {
	loadedTile := false
	defer timer.New("processTile").Stop()
	glog.Infof("Starting processtile: %t - %t", useCached, reloadRawTile)

	var newLabeledTile, ignoredLabeledTile *LabeledTile = nil, nil
	var err error

	// Load the labeled tiles from cache. This will require no new diffs
	// since they have already been calculated for the cached tile.
	if useCached {
		newLabeledTile, ignoredLabeledTile = a.getCachedTiles()
	}

	// If we don't have labeled tiles at this point we need to get a raw tile
	// and build a labeled tile.
	if newLabeledTile == nil {
		// Either use a tile already in memory or load a new one.
		var tile *ptypes.Tile
		if reloadRawTile || (a.lastRawTile == nil) {
			tile, err = a.storages.GetLastTileTrimmed(true)
			if err != nil {
				glog.Errorf("Error retrieving trimmed tile: %s\n", err)
				errorTileLoadingCounter.Inc(1)
				return false
			}
			glog.Infof("TileLen: %d", tile.LastCommitIndex()+1)

			a.lastRawTile = tile
			loadedTile = true
			glog.Infoln("Loaded new tile from disk.")
		} else {
			tile = a.lastRawTile
			glog.Infoln("Reusing last raw tile.")
		}

		newLabeledTile, ignoredLabeledTile = a.partitionRawTile(tile)

		a.prepDiffsForLabeledTile(newLabeledTile)
		a.prepDiffsForLabeledTile(ignoredLabeledTile)
		a.cacheTiles(newLabeledTile, ignoredLabeledTile)
	}

	glog.Infof("Tests in newLabeledTiles    : %d", len(newLabeledTile.Traces))
	glog.Infof("Tests in ignoredLabeledTiles: %d", len(ignoredLabeledTile.Traces))

	// Protect the tile and expectations with the write lock.
	a.mutex.Lock()
	defer a.mutex.Unlock()

	// Retrieve the current expectations.
	expectations, err := a.storages.ExpectationsStore.Get()
	if err != nil {
		glog.Errorf("Error retrieving expectations: %s", err)
		return false
	}
	a.setDerivedOutputs(newLabeledTile, expectations, a.current, false)
	a.setDerivedOutputs(ignoredLabeledTile, expectations, a.ignored, false)

	glog.Info("Done processing tiles.")
	runsCounter.Inc(1)
	a.loopCounter++

	return loadedTile
}

// completeDiffs forces the DiffStore to precalculate the diffs
// between all digests (within a test).
// TODO(stephana): This is currently not used, but will be enabled once
// the filediffstore can efficiently handle complete diffs.
func (a *Analyzer) completeDiffs(labeledTile *LabeledTile) {
	var wg sync.WaitGroup
	for _, traces := range labeledTile.Traces {
		wg.Add(1)
		go func(traces []*LabeledTrace) {
			digestsList := make([][]string, 0, len(traces))
			for _, t := range traces {
				digestsList = append(digestsList, t.Digests)
			}
			allDigests := util.UnionStrings(digestsList...)
			a.storages.DiffStore.CalculateDiffs(allDigests)
			wg.Done()
		}(traces)
	}

	wg.Wait()
}

// prepDiffsForLabeledTile forces the DiffStore to precalculate the diffs
// between new digests. We do this outside the locking so that when we are
// inside the lock almost all diffs will be cached already.
func (a *Analyzer) prepDiffsForLabeledTile(labeledTile *LabeledTile) {
	glog.Infof("Starting prep diffs")
	// Get the current expectations.
	a.mutex.RLock()
	expectations, err := a.storages.ExpectationsStore.Get()
	a.mutex.RUnlock()
	if err != nil {
		glog.Errorf("Unable to read expectations: %s", err)
		return
	}

	// Make a dummy call to setDerivedOutputs to force a diff on new
	// digest pairs.
	tempState := AnalyzeState{}
	a.setDerivedOutputs(labeledTile, expectations, &tempState, true)
	glog.Infof("Done prep diffs")
}

// partitionRawTile partitions the input tile into two tiles (current and ignored)
// and derives the output data structures for both.
func (a *Analyzer) partitionRawTile(tile *ptypes.Tile) (*LabeledTile, *LabeledTile) {
	glog.Info("Processing tile into LabeledTile ...")

	// Shared between both tiles.
	tileLen := tile.LastCommitIndex() + 1

	// Set the up the result tile and a tile for ignored traces.
	resultTile := NewLabeledTile()
	resultTile.Commits = tile.Commits[:tileLen]
	resultCommitsByDigestMap := map[string]map[string]map[int]bool{}

	ignoredTile := NewLabeledTile()
	ignoredTile.Commits = tile.Commits[:tileLen]
	ignoredCommitsByDigestMap := map[string]map[string]map[int]bool{}

	// Get the digests that are unavailable, e.g. they cannot be fetched
	// from GS or they are not valid images.
	unavailableDigests := a.storages.DiffStore.UnavailableDigests()
	glog.Infof("Unavailable digests: %v", unavailableDigests)

	// Get the rule matcher to find traces to ignore.
	ruleMatcher, err := a.storages.IgnoreStore.BuildRuleMatcher()
	if err != nil {
		glog.Errorf("Unable to build rule matcher: %s", err)
	}

	// Note: We are assumming that the number and order of traces will change
	// over time.
	var targetTile *LabeledTile
	var commitsByDigestMap map[string]map[string]map[int]bool
	for _, v := range tile.Traces {
		// Determine if this tile is to be in the result or the ignored tile.
		matchedRules, isIgnored := ruleMatcher(v.Params())
		if isIgnored {
			targetTile = ignoredTile
			commitsByDigestMap = ignoredCommitsByDigestMap
		} else {
			targetTile = resultTile
			commitsByDigestMap = resultCommitsByDigestMap
		}

		tempCommitIds := make([]int, 0, tileLen)
		tempLabels := make([]types.Label, 0, tileLen)
		tempDigests := make([]string, 0, tileLen)
		gTrace := v.(*ptypes.GoldenTrace)
		testName := gTrace.Params()[types.PRIMARY_KEY_FIELD]

		// Iterate over the digests in this trace.
		for i, v := range gTrace.Values[:tileLen] {
			if (v != ptypes.MISSING_DIGEST) && !unavailableDigests[v] {
				tempCommitIds = append(tempCommitIds, i)
				tempDigests = append(tempDigests, v)
				tempLabels = append(tempLabels, types.UNTRIAGED)

				// Keep track of the commits by digest.
				if _, ok := commitsByDigestMap[testName]; !ok {
					commitsByDigestMap[testName] = map[string]map[int]bool{v: map[int]bool{i: true}}
				} else if _, ok := commitsByDigestMap[testName][v]; !ok {
					commitsByDigestMap[testName][v] = map[int]bool{i: true}
				} else {
					commitsByDigestMap[testName][v][i] = true
				}
			}
		}

		// Only consider traces that are not empty.
		if len(tempLabels) > 0 {
			// Label the digests and add them to the labeled traces.
			_, targetLabeledTrace := targetTile.getLabeledTrace(v)
			targetLabeledTrace.addLabeledDigests(tempCommitIds, tempDigests, tempLabels)
			if isIgnored {
				targetLabeledTrace.addIgnoreRules(matchedRules)
			}
		}
	}

	getCommitsByDigest(resultTile, resultCommitsByDigestMap)
	getCommitsByDigest(ignoredTile, ignoredCommitsByDigestMap)

	glog.Info("Done processing tile into LabeledTile.")
	return resultTile, ignoredTile
}

func getCommitsByDigest(labeledTile *LabeledTile, commitsByDigestMap map[string]map[string]map[int]bool) {
	for testName, cbd := range commitsByDigestMap {
		labeledTile.CommitsByDigest[testName] = make(map[string][]int, len(cbd))
		for d, commitIds := range cbd {
			labeledTile.CommitsByDigest[testName][d] = util.KeysOfIntSet(commitIds)
			sort.Ints(labeledTile.CommitsByDigest[testName][d])
		}
	}
}

// setDerivedOutputs derives the output data from the given tile and
// updates the outputs and tile in the analyzer.
func (a *Analyzer) setDerivedOutputs(labeledTile *LabeledTile, expectations *expstorage.Expectations, state *AnalyzeState, prep bool) {
	// Assign all the labels.
	for testName, traces := range labeledTile.Traces {
		for _, trace := range traces {
			labelDigests(testName, trace.Digests, trace.Labels, expectations)
		}
	}

	// Generate the lookup index for the tile and get all parameters.
	state.Index = NewLabeledTileIndex(labeledTile)
	state.Tile = labeledTile
	state.TestDetails = a.getTestDetails(state)

	// Don't calculate these during prep runs.
	if !prep {
		state.Status = calcStatus(state)
		state.BlameLists = getBlameLists(state.Tile)
	}
}

// updateLabels iterates over the traces in of the tiles that have changed and
// labels them according to our current expecatations.

// updateDerivedOutputs
func (a *Analyzer) updateDerivedOutputs(labeledTestDigests map[string]types.TestClassification, expectations *expstorage.Expectations, state *AnalyzeState) {
	// Update the labels of the traces that have changed.
	for testName := range labeledTestDigests {
		if traces, ok := state.Tile.Traces[testName]; ok {
			for _, trace := range traces {
				// Note: This is potentially slower than using labels in
				// labeledTestDigests directly, but it keeps the code simpler.
				labelDigests(testName, trace.Digests, trace.Labels, expectations)
			}
		}
	}

	// Update all the output data structures.
	// TODO(stephana): Evaluate whether the counts are really useful or if they can be removed.
	// If we need them uncomment the following line and implement the corresponding function.
	//a.updateOutputCounts(labeledTestDigests)

	// Update the tests that have changed and the status.
	a.updateTestDetails(labeledTestDigests, state)
	state.Status = calcStatus(state)
}

// labelDigest assignes a label to the given digests based on the expectations.
// Its assumes that targetLabels are pre-initialized, usualy with UNTRIAGED,
// because it will not change the label if the given test and digest cannot be
// found.
func labelDigests(testName string, digests []string, targetLabels []types.Label, expectations *expstorage.Expectations) {
	for idx, digest := range digests {
		if test, ok := expectations.Tests[testName]; ok {
			if foundLabel, ok := test[digest]; ok {
				targetLabels[idx] = foundLabel
			}
		}
	}
}

// getUntriagedTestDetails returns the untriaged digests of a specific test that
// match the given query. In addition to the digests it returns the query
// that was used to retrieve them.
func (a *Analyzer) getUntriagedTestDetails(query, effectiveQuery map[string][]string, includeAllTests bool) map[string]map[string]*GUIUntriagedDigest {
	traces, startCommitId, endCommitId, showHead := a.current.Index.query(query, effectiveQuery)
	endCommitId++

	if len(effectiveQuery) == 0 {
		return nil
	}

	ret := make(map[string]map[string]*GUIUntriagedDigest, len(a.current.TestDetails.Tests))

	// This includes an empty list for tests that we have not found.
	if includeAllTests {
		for _, testName := range a.current.Index.getTestNames(query) {
			ret[testName] = nil
		}
	}

	if !showHead {
		for _, trace := range traces {
			testName := trace.Params[types.PRIMARY_KEY_FIELD]
			current := a.current.TestDetails.lookup(testName).Untriaged

			startIdx := sort.SearchInts(trace.CommitIds, startCommitId)
			endIdx := sort.SearchInts(trace.CommitIds, endCommitId)
			if (endIdx < len(trace.CommitIds)) && (trace.CommitIds[endIdx] == endCommitId) {
				endIdx++
			}

			for idx := startIdx; idx < endIdx; idx++ {
				if trace.Labels[idx] == types.UNTRIAGED {
					if found, ok := ret[testName]; !ok || found == nil {
						ret[testName] = make(map[string]*GUIUntriagedDigest, len(current))
					}
					ret[testName][trace.Digests[idx]] = current[trace.Digests[idx]]
				}
			}
		}
	} else {
		for _, trace := range traces {
			lastIdx := len(trace.Labels) - 1
			if (lastIdx >= 0) && (trace.Labels[lastIdx] == types.UNTRIAGED) {
				testName := trace.Params[types.PRIMARY_KEY_FIELD]
				current := a.current.TestDetails.lookup(testName).Untriaged
				if found, ok := ret[testName]; !ok || found == nil {
					ret[testName] = map[string]*GUIUntriagedDigest{}
				}
				ret[testName][trace.Digests[lastIdx]] = current[trace.Digests[lastIdx]]
			}
		}
	}

	return ret
}
