package indexer

import (
	"context"
	"errors"
	"fmt"
	"sort"
	"testing"
	"time"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/mock"
	"github.com/stretchr/testify/require"

	"go.skia.org/infra/go/paramtools"
	"go.skia.org/infra/go/testutils"
	"go.skia.org/infra/go/testutils/unittest"
	"go.skia.org/infra/golden/go/blame"
	"go.skia.org/infra/golden/go/clstore"
	mock_clstore "go.skia.org/infra/golden/go/clstore/mocks"
	"go.skia.org/infra/golden/go/code_review"
	"go.skia.org/infra/golden/go/digest_counter"
	"go.skia.org/infra/golden/go/expectations"
	mock_expectations "go.skia.org/infra/golden/go/expectations/mocks"
	"go.skia.org/infra/golden/go/mocks"
	"go.skia.org/infra/golden/go/paramsets"
	"go.skia.org/infra/golden/go/summary"
	gtestutils "go.skia.org/infra/golden/go/testutils"
	data "go.skia.org/infra/golden/go/testutils/data_three_devices"
	"go.skia.org/infra/golden/go/tiling"
	"go.skia.org/infra/golden/go/tjstore"
	mock_tjstore "go.skia.org/infra/golden/go/tjstore/mocks"
	"go.skia.org/infra/golden/go/types"
)

// TestIndexer_ExecutePipeline_NoChangelistsToIndex_Success tests a full indexing run, assuming
// nothing crashes or returns an error..
func TestIndexer_ExecutePipeline_Success(t *testing.T) {
	unittest.SmallTest(t)

	mes := &mock_expectations.Store{}
	mgc := &mocks.GCSClient{}

	defer mes.AssertExpectations(t)
	defer mgc.AssertExpectations(t)

	ct, _, _ := makeComplexTileWithCrosshatchIgnores()

	ic := IndexerConfig{
		ExpectationsStore: mes,
		GCSClient:         mgc,
	}
	wg, async, _ := gtestutils.AsyncHelpers()

	allTestDigests := types.DigestSlice{data.AlphaPositiveDigest, data.AlphaNegativeDigest, data.AlphaUntriagedDigest,
		data.BetaPositiveDigest, data.BetaUntriagedDigest}
	sort.Sort(allTestDigests)

	mes.On("Get", testutils.AnyContext).Return(data.MakeTestExpectations(), nil)

	dMatcher := mock.MatchedBy(func(digests types.DigestSlice) bool {
		sort.Sort(digests)

		assert.Equal(t, allTestDigests, digests)
		return true
	})

	async(mgc.On("WriteKnownDigests", testutils.AnyContext, dMatcher).Return(nil))

	ixr, err := New(context.Background(), ic, 0)
	require.NoError(t, err)

	err = ixr.executePipeline(context.Background(), ct)
	require.NoError(t, err)
	actualIndex := ixr.GetIndex()
	require.NotNil(t, actualIndex)

	// Block until all async calls are finished so the assertExpectations calls
	// can properly check that their functions were called.
	wg.Wait()
}

// TestIndexerPartialUpdate tests the part of indexer that runs when expectations change
// and we need to re-index a subset of the data, namely that which had tests change
// (e.g. from Untriaged to Positive or whatever).
func TestIndexerPartialUpdate(t *testing.T) {
	unittest.SmallTest(t)

	mes := &mock_expectations.Store{}

	defer mes.AssertExpectations(t)

	ct, fullTile, partialTile := makeComplexTileWithCrosshatchIgnores()
	require.NotEqual(t, fullTile, partialTile)

	mes.On("Get", testutils.AnyContext).Return(data.MakeTestExpectations(), nil)

	ic := IndexerConfig{
		ExpectationsStore: mes,
	}

	ixr, err := New(context.Background(), ic, 0)
	require.NoError(t, err)

	alphaOnly := []*summary.TriageStatus{
		{
			Name:      data.AlphaTest,
			Untriaged: 1,
			UntHashes: types.DigestSlice{data.AlphaUntriagedDigest},
		},
	}

	ixr.lastMasterIndex = &SearchIndex{
		searchIndexConfig: searchIndexConfig{
			expectationsStore: mes,
		},
		summaries: [2]countsAndBlames{alphaOnly, alphaOnly},
		dCounters: [2]digest_counter.DigestCounter{
			digest_counter.New(partialTile),
			digest_counter.New(fullTile),
		},
		preSliced: map[preSliceGroup][]*tiling.TracePair{},

		cpxTile: ct,
	}
	require.NoError(t, preSliceData(context.Background(), ixr.lastMasterIndex))

	ixr.indexTests(context.Background(), []expectations.ID{
		{
			// Pretend this digest was just triaged.
			Grouping: data.BetaTest,
			Digest:   data.BetaPositiveDigest,
		},
	})

	actualIndex := ixr.GetIndex()
	require.NotNil(t, actualIndex)

	sm := actualIndex.GetSummaries(types.ExcludeIgnoredTraces)
	require.Len(t, sm, 2)
	assert.Equal(t, data.AlphaTest, sm[0].Name)
	assert.Equal(t, data.BetaTest, sm[1].Name)

	// Spot check the summaries themselves.
	require.Equal(t, types.DigestSlice{data.AlphaUntriagedDigest}, sm[0].UntHashes)

	require.Equal(t, &summary.TriageStatus{
		Name:      data.BetaTest,
		Pos:       1,
		Neg:       0,
		Untriaged: 0, // Reminder that the untriaged image for BetaTest was ignored by the rules.
		UntHashes: types.DigestSlice{},
		Num:       1,
		Corpus:    "gm",
		Blame:     []blame.WeightedBlame{},
	}, sm[1])
}

func TestIndexer_CalcChangelistIndices_NoPreviousIndices_Success(t *testing.T) {
	unittest.SmallTest(t)

	const gerritCRS = "gerrit"
	const firstCLID = "111111"
	const patchsetFoxtrot = "foxtrot"
	const secondCLID = "22222"
	const patchsetSam = "sam"

	firstCombinedID := tjstore.CombinedPSID{CL: firstCLID, CRS: gerritCRS, PS: patchsetFoxtrot}
	secondCombinedID := tjstore.CombinedPSID{CL: secondCLID, CRS: gerritCRS, PS: patchsetSam}

	mcs := &mock_clstore.Store{}
	mes := &mock_expectations.Store{}
	mts := &mock_tjstore.Store{}

	masterExp := expectations.Expectations{}
	masterExp.Set(data.AlphaTest, data.AlphaPositiveDigest, expectations.Positive)

	firstCLExp := expectations.Expectations{}
	firstCLExp.Set(data.AlphaTest, data.AlphaNegativeDigest, expectations.Negative)

	// secondCL has no additional expectations
	mes.On("Get", testutils.AnyContext).Return(&masterExp, nil)
	loadChangelistExpectations(mes, gerritCRS, map[string]*expectations.Expectations{
		firstCLID:  &firstCLExp,
		secondCLID: {},
	})

	searchOptionsMatcher := mock.MatchedBy(func(so clstore.SearchOptions) bool {
		assert.Zero(t, so.StartIdx)
		assert.True(t, so.OpenCLsOnly)
		assert.Equal(t, maxCLsToIndex, so.Limit)
		assert.NotZero(t, so.After)
		return true
	})
	mcs.On("GetChangelists", testutils.AnyContext, searchOptionsMatcher).Return([]code_review.Changelist{
		// We don't look at the other fields since the index doesn't previously exist for this CL.
		{SystemID: firstCLID},
		{SystemID: secondCLID},
	}, 0, nil)
	// Reminder: only the most recent patchset is indexed.
	mcs.On("GetPatchsets", testutils.AnyContext, firstCLID).Return([]code_review.Patchset{
		{SystemID: patchsetFoxtrot}, // all other fields ignored from Patchset.
	}, nil)
	mcs.On("GetPatchsets", testutils.AnyContext, secondCLID).Return([]code_review.Patchset{
		{SystemID: "not the most recent, so it is ignored"},
		{SystemID: patchsetSam},
	}, nil)

	androidGroup := paramtools.Params{
		"os":    "Android",
		"model": "crosshatch",
	}
	iosGroup := paramtools.Params{
		"os":    "iOS",
		"model": "iphone3",
	}
	firstOptionalGroup := paramtools.Params{
		"color_gamut": "wide",
	}
	secondOptionalGroup := paramtools.Params{
		"color_gamut": "narrow",
		"day_of_week": "wednesday",
	}

	resultParams := paramtools.Params{ // all data points are for the same test.
		types.CorpusField:     "some_corpus",
		types.PrimaryKeyField: string(data.AlphaTest),
	}

	mts.On("GetResults", testutils.AnyContext, firstCombinedID, time.Time{}).Return([]tjstore.TryJobResult{
		{
			ResultParams: resultParams,
			GroupParams:  androidGroup,
			Options:      firstOptionalGroup,
			Digest:       data.AlphaPositiveDigest,
			// Other fields ignored
		},
		{
			ResultParams: resultParams,
			GroupParams:  iosGroup,
			Options:      firstOptionalGroup,
			Digest:       data.AlphaNegativeDigest,
		},
		{
			ResultParams: resultParams,
			GroupParams:  androidGroup,
			Options:      secondOptionalGroup,
			Digest:       data.AlphaUntriagedDigest,
		},
	}, nil)
	mts.On("GetResults", testutils.AnyContext, secondCombinedID, time.Time{}).Return([]tjstore.TryJobResult{
		{
			ResultParams: resultParams,
			GroupParams:  androidGroup,
			Options:      firstOptionalGroup,
			Digest:       data.AlphaPositiveDigest,
		},
		{
			ResultParams: resultParams,
			GroupParams:  iosGroup,
			Options:      firstOptionalGroup,
			// Note, for this CL, this digest has not yet been triaged.
			Digest: data.AlphaNegativeDigest,
		},
		{
			ResultParams: resultParams,
			GroupParams:  androidGroup,
			Options:      firstOptionalGroup,
			Digest:       data.AlphaUntriagedDigest,
		},
	}, nil)

	ctx := context.Background()
	ic := IndexerConfig{
		ExpectationsStore: mes,
		TryJobStore:       mts,
		ReviewSystems: []clstore.ReviewSystem{
			{
				ID:    gerritCRS,
				Store: mcs,
				// URLTemplate and Client are unused here
			},
		},
	}
	ixr, err := New(ctx, ic, 0)
	require.NoError(t, err)
	ixr.changelistsReindexed.Reset()
	ixr.lastMasterIndex = fakeSearchIndex()

	ixr.calcChangelistIndices(ctx)

	clIdx := ixr.GetIndexForCL(gerritCRS, firstCLID)
	assert.NotNil(t, clIdx)
	assert.Equal(t, firstCombinedID, clIdx.LatestPatchset)
	assert.Len(t, clIdx.UntriagedResults, 1)
	assert.Equal(t, data.AlphaUntriagedDigest, clIdx.UntriagedResults[0].Digest)
	require.NotNil(t, clIdx.ParamSet)
	clIdx.ParamSet.Normalize()
	assert.Equal(t, paramtools.ParamSet{
		"color_gamut": []string{"narrow", "wide"},
		"day_of_week": []string{"wednesday"},
		"model":       []string{"crosshatch", "iphone3"},
		"name":        []string{"test_alpha"},
		"os":          []string{"Android", "iOS"},
		"source_type": []string{"some_corpus"},
	}, clIdx.ParamSet)

	clIdx = ixr.GetIndexForCL(gerritCRS, secondCLID)
	assert.NotNil(t, clIdx)
	assert.Equal(t, secondCombinedID, clIdx.LatestPatchset)
	assert.Len(t, clIdx.UntriagedResults, 2)
	// Reminder, AlphaNegativeDigest was not triaged in the CL expectations for secondCLID
	assert.Equal(t, data.AlphaNegativeDigest, clIdx.UntriagedResults[0].Digest)
	assert.Equal(t, data.AlphaUntriagedDigest, clIdx.UntriagedResults[1].Digest)
	require.NotNil(t, clIdx.ParamSet)
	clIdx.ParamSet.Normalize()
	// secondCLID does not have the secondOptionalGroup, so it lacks a few key/values
	assert.Equal(t, paramtools.ParamSet{
		"color_gamut": []string{"wide"},
		"model":       []string{"crosshatch", "iphone3"},
		"name":        []string{"test_alpha"},
		"os":          []string{"Android", "iOS"},
		"source_type": []string{"some_corpus"},
	}, clIdx.ParamSet)

	assert.Equal(t, int64(2), ixr.changelistsReindexed.Get())
}

// fakeSearchIndex returns an arbitrary SearchIndex with enough data to compute CL diff messages.
func fakeSearchIndex() *SearchIndex {
	_, tile, _ := makeComplexTileWithCrosshatchIgnores()
	return &SearchIndex{
		dCounters: [2]digest_counter.DigestCounter{digest_counter.New(tile), digest_counter.New(tile)},
	}
}

func TestIndexer_CalcChangelistIndices_HasIndexForPreviousPS_Success(t *testing.T) {
	unittest.SmallTest(t)

	const gerritCRS = "gerrit"
	const clID = "111111"
	const firstPatchset = "firstPS"
	const secondPatchset = "secondPS"
	firstPatchsetCombinedID := tjstore.CombinedPSID{CL: clID, CRS: gerritCRS, PS: firstPatchset}
	secondPatchsetCombinedID := tjstore.CombinedPSID{CL: clID, CRS: gerritCRS, PS: secondPatchset}

	longAgo := time.Date(2020, time.April, 15, 15, 15, 0, 0, time.UTC)
	recently := time.Date(2020, time.May, 5, 12, 12, 0, 0, time.UTC)

	mcs := &mock_clstore.Store{}
	mes := &mock_expectations.Store{}
	mts := &mock_tjstore.Store{}

	masterExp := expectations.Expectations{}
	masterExp.Set(data.AlphaTest, data.AlphaPositiveDigest, expectations.Positive)
	masterExp.Set(data.AlphaTest, data.AlphaNegativeDigest, expectations.Negative)

	// The CL has no additional expectations.
	mes.On("Get", testutils.AnyContext).Return(&masterExp, nil)
	loadChangelistExpectations(mes, gerritCRS, map[string]*expectations.Expectations{
		clID: {},
	})

	mcs.On("GetChangelists", testutils.AnyContext, mock.Anything).Return([]code_review.Changelist{
		{
			SystemID: clID,
			Updated:  recently,
		},
	}, 0, nil)

	mcs.On("GetPatchsets", testutils.AnyContext, clID).Return([]code_review.Patchset{
		{SystemID: firstPatchset}, // all other fields ignored from patch set.
		{SystemID: secondPatchset},
	}, nil)

	androidGroup := paramtools.Params{
		"os":    "Android",
		"model": "crosshatch",
	}

	mts.On("GetResults", testutils.AnyContext, secondPatchsetCombinedID, time.Time{}).Return([]tjstore.TryJobResult{
		{
			ResultParams: paramtools.Params{types.PrimaryKeyField: string(data.AlphaTest)},
			GroupParams:  androidGroup,
			Digest:       data.AlphaPositiveDigest,
			// Other fields ignored
		},
		{
			ResultParams: paramtools.Params{types.PrimaryKeyField: string(data.AlphaTest)},
			GroupParams:  androidGroup,
			Digest:       data.AlphaNegativeDigest,
		},
		{
			ResultParams: paramtools.Params{types.PrimaryKeyField: string(data.AlphaTest)},
			GroupParams:  androidGroup,
			Digest:       data.AlphaUntriagedDigest,
		},
	}, nil)

	ctx := context.Background()
	ic := IndexerConfig{
		ExpectationsStore: mes,
		TryJobStore:       mts,
		ReviewSystems: []clstore.ReviewSystem{
			{
				ID:    gerritCRS,
				Store: mcs,
				// URLTemplate and Client are unused here
			},
		},
	}
	ixr, err := New(ctx, ic, 0)
	require.NoError(t, err)
	ixr.changelistsReindexed.Reset()

	// The scenario here is that the first Patchset generated three untriaged digests.After that
	// index was computed, the user triaged AlphaPositiveDigest and AlphaNegativeDigest, and the
	// remainder of the data was uploaded to secondPatchset. After the index is recomputed, the index
	// should be replaced with the new data (which reflects the new expectations).
	previousIdx := ChangelistIndex{
		LatestPatchset: firstPatchsetCombinedID,
		UntriagedResults: []tjstore.TryJobResult{
			{
				ResultParams: paramtools.Params{types.PrimaryKeyField: string(data.AlphaTest)},
				Digest:       data.AlphaPositiveDigest,
				// Other fields ignored
			},
			{
				ResultParams: paramtools.Params{types.PrimaryKeyField: string(data.AlphaTest)},
				Digest:       data.AlphaNegativeDigest,
			},
			{
				ResultParams: paramtools.Params{types.PrimaryKeyField: string(data.AlphaTest)},
				Digest:       data.AlphaUntriagedDigest,
			},
		},
		ParamSet: paramtools.ParamSet{
			// This ParamSet is purposely incomplete (i.e. no data.AlphaTest) to make sure new data is
			// merged in correctly.
			types.PrimaryKeyField: []string{"this_test_was_here_before"},
			"os":                  []string{"Android", "iOS"},
			"model":               []string{"bluefish", "redfish"},
		},
		ComputedTS: longAgo,
	}
	ixr.changelistIndices.Set("gerrit_111111", &previousIdx, 0)
	ixr.lastMasterIndex = fakeSearchIndex()

	ixr.calcChangelistIndices(ctx)

	clIdx := ixr.GetIndexForCL(gerritCRS, clID)
	assert.NotNil(t, clIdx)
	assert.Equal(t, secondPatchsetCombinedID, clIdx.LatestPatchset)
	assert.True(t, clIdx.ComputedTS.After(longAgo)) // should be updated
	assert.Len(t, clIdx.UntriagedResults, 1)
	assert.Equal(t, data.AlphaUntriagedDigest, clIdx.UntriagedResults[0].Digest)
	require.NotNil(t, clIdx.ParamSet)
	clIdx.ParamSet.Normalize()
	assert.Equal(t, paramtools.ParamSet{
		"model": []string{"bluefish", "crosshatch", "redfish"},
		"name":  []string{"test_alpha", "this_test_was_here_before"},
		"os":    []string{"Android", "iOS"},
	}, clIdx.ParamSet)
	assert.Equal(t, int64(1), ixr.changelistsReindexed.Get())
}

func TestIndexer_CalcChangelistIndices_HasIndexForCurrentPS_IncrementalUpdateSuccess(t *testing.T) {
	unittest.SmallTest(t)

	const gerritCRS = "gerrit"
	const clID = "111111"
	const firstPatchset = "firstPS"
	const firstUntriagedDigest = types.Digest("11111111111111111111")
	const secondUntriagedDigest = types.Digest("22222222222222222222")
	const thirdUntriagedDigest = types.Digest("33333333333333333333")

	firstPatchsetCombinedID := tjstore.CombinedPSID{CL: clID, CRS: gerritCRS, PS: firstPatchset}

	longAgo := time.Date(2020, time.April, 15, 15, 15, 0, 0, time.UTC)
	recently := time.Date(2020, time.May, 5, 12, 12, 0, 0, time.UTC)

	mcs := &mock_clstore.Store{}
	mes := &mock_expectations.Store{}
	mts := &mock_tjstore.Store{}

	// All digests are untriaged
	masterExp := expectations.Expectations{}

	// The CL has no additional expectations.
	mes.On("Get", testutils.AnyContext).Return(&masterExp, nil)
	loadChangelistExpectations(mes, gerritCRS, map[string]*expectations.Expectations{
		clID: {},
	})

	mcs.On("GetChangelists", testutils.AnyContext, mock.Anything).Return([]code_review.Changelist{
		{
			SystemID: clID,
			Updated:  recently,
		},
	}, 0, nil)

	mcs.On("GetPatchsets", testutils.AnyContext, clID).Return([]code_review.Patchset{
		{SystemID: firstPatchset}, // all other fields ignored from patch set.
	}, nil)

	androidGroup := paramtools.Params{
		"os":    "Android",
		"model": "crosshatch",
	}

	// Note that this time is based on the previous indexed time.
	mts.On("GetResults", testutils.AnyContext, firstPatchsetCombinedID, longAgo).Return([]tjstore.TryJobResult{
		{
			ResultParams: paramtools.Params{types.PrimaryKeyField: string(data.AlphaTest)},
			GroupParams:  androidGroup,
			Digest:       secondUntriagedDigest,
		},
		{
			ResultParams: paramtools.Params{types.PrimaryKeyField: string(data.AlphaTest)},
			GroupParams:  androidGroup,
			Digest:       thirdUntriagedDigest,
		},
	}, nil)

	ctx := context.Background()
	ic := IndexerConfig{
		ExpectationsStore: mes,
		TryJobStore:       mts,
		ReviewSystems: []clstore.ReviewSystem{
			{
				ID:    gerritCRS,
				Store: mcs,
				// URLTemplate and Client are unused here
			},
		},
	}
	ixr, err := New(ctx, ic, 0)
	require.NoError(t, err)
	ixr.changelistsReindexed.Reset()

	// The scenario here is that the first index for this patchset identified two untriaged digests.
	// Later, .
	previousIdx := ChangelistIndex{
		LatestPatchset: firstPatchsetCombinedID,
		UntriagedResults: []tjstore.TryJobResult{
			{
				ResultParams: paramtools.Params{types.PrimaryKeyField: string(data.AlphaTest)},
				Digest:       firstUntriagedDigest,
				// Other fields ignored
			},
			{
				ResultParams: paramtools.Params{types.PrimaryKeyField: string(data.AlphaTest)},
				Digest:       secondUntriagedDigest,
			},
		},
		ParamSet: paramtools.ParamSet{
			// This ParamSet is purposely incomplete (i.e. no data.AlphaTest) to make sure new data is
			// merged in correctly.
			types.PrimaryKeyField: []string{"this_test_was_here_before"},
			"os":                  []string{"Android", "iOS"},
			"model":               []string{"bluefish", "redfish"},
		},
		ComputedTS: longAgo,
	}
	ixr.changelistIndices.Set("gerrit_111111", &previousIdx, 0)
	ixr.lastMasterIndex = fakeSearchIndex()
	ixr.calcChangelistIndices(ctx)

	clIdx := ixr.GetIndexForCL(gerritCRS, clID)
	assert.NotNil(t, clIdx)
	assert.Equal(t, firstPatchsetCombinedID, clIdx.LatestPatchset)
	assert.True(t, clIdx.ComputedTS.After(longAgo)) // should be updated
	assert.Len(t, clIdx.UntriagedResults, 3)
	assert.Equal(t, firstUntriagedDigest, clIdx.UntriagedResults[0].Digest)
	assert.Equal(t, secondUntriagedDigest, clIdx.UntriagedResults[1].Digest)
	assert.Equal(t, thirdUntriagedDigest, clIdx.UntriagedResults[2].Digest)
	require.NotNil(t, clIdx.ParamSet)
	clIdx.ParamSet.Normalize()
	assert.Equal(t, paramtools.ParamSet{
		"model": []string{"bluefish", "crosshatch", "redfish"},
		"name":  []string{"test_alpha", "this_test_was_here_before"},
		"os":    []string{"Android", "iOS"},
	}, clIdx.ParamSet)
	assert.Equal(t, int64(1), ixr.changelistsReindexed.Get())
}

func TestIndexer_CalcChangelistIndices_PreviousIndexDoesNotNeedUpdating_Success(t *testing.T) {
	unittest.SmallTest(t)

	const gerritCRS = "gerrit"
	const clID = "111111"
	const thePatchset = "firstPS"
	thePatchsetCombinedID := tjstore.CombinedPSID{CL: clID, CRS: gerritCRS, PS: thePatchset}

	now := time.Date(2020, time.May, 15, 15, 15, 0, 0, time.UTC)
	fiveMinAgo := now.Add(-5 * time.Minute)
	tenMinAgo := now.Add(-10 * time.Minute)

	mcs := &mock_clstore.Store{}
	mes := &mock_expectations.Store{}

	masterExp := expectations.Expectations{}
	masterExp.Set(data.AlphaTest, data.AlphaPositiveDigest, expectations.Positive)
	masterExp.Set(data.AlphaTest, data.AlphaNegativeDigest, expectations.Negative)

	// The CL has no additional expectations.
	mes.On("Get", testutils.AnyContext).Return(&masterExp, nil)
	loadChangelistExpectations(mes, gerritCRS, map[string]*expectations.Expectations{
		clID: {},
	})

	mcs.On("GetChangelists", testutils.AnyContext, mock.Anything).Return([]code_review.Changelist{
		{
			SystemID: clID,
			// CL was updated 10 minutes ago. That is, the ingester last got data from this CL 10 min
			// ago.
			Updated: tenMinAgo,
		},
	}, 0, nil)

	mcs.On("GetPatchsets", testutils.AnyContext, clID).Return([]code_review.Patchset{
		{SystemID: thePatchset}, // all other fields ignored from patch set.
	}, nil)

	ctx := context.Background()
	ic := IndexerConfig{
		ExpectationsStore: mes,
		ReviewSystems: []clstore.ReviewSystem{
			{
				ID:    gerritCRS,
				Store: mcs,
				// URLTemplate and Client are unused here
			},
		},
	}
	ixr, err := New(ctx, ic, 0)
	require.NoError(t, err)
	ixr.changelistsReindexed.Reset()

	// The scenario here is that the CL has not been updated since the index was made, so the index
	// should not be updated.
	previousIdx := ChangelistIndex{
		LatestPatchset: thePatchsetCombinedID,
		UntriagedResults: []tjstore.TryJobResult{
			{
				ResultParams: paramtools.Params{types.PrimaryKeyField: string(data.AlphaTest)},
				Digest:       data.AlphaUntriagedDigest,
				// Other fields ignored
			},
		},
		ParamSet: paramtools.ParamSet{
			// This ParamSet is purposely incomplete (i.e. no data.AlphaTest) to make sure new data is
			// merged in correctly.
			types.PrimaryKeyField: []string{"this_test_was_here_before"},
			"os":                  []string{"Android", "iOS"},
			"model":               []string{"bluefish", "redfish"},
		},
		ComputedTS: fiveMinAgo,
	}
	ixr.changelistIndices.Set("gerrit_111111", &previousIdx, 0)

	ixr.calcChangelistIndices(ctx)

	clIdx := ixr.GetIndexForCL(gerritCRS, clID)
	assert.NotNil(t, clIdx)
	assert.Equal(t, thePatchsetCombinedID, clIdx.LatestPatchset)
	assert.Equal(t, clIdx.ComputedTS, fiveMinAgo) // should not be updated
	assert.Len(t, clIdx.UntriagedResults, 1)
	assert.Equal(t, int64(0), ixr.changelistsReindexed.Get())
}

// TestPreSlicedTracesCreatedCorrectly makes sure that we pre-slice the data based on IgnoreState,
// then Corpus, then TestName.
func TestPreSlicedTracesCreatedCorrectly(t *testing.T) {
	unittest.SmallTest(t)

	ct, _, _ := makeComplexTileWithCrosshatchIgnores()

	si := &SearchIndex{
		preSliced: map[preSliceGroup][]*tiling.TracePair{},
		cpxTile:   ct,
	}
	require.NoError(t, preSliceData(context.Background(), si))

	// (2 IgnoreStates) + (2 IgnoreStates * 1 corpus) + (2 IgnoreStates * 1 corpus * 2 tests)
	assert.Len(t, si.preSliced, 8)
	allCombos := []preSliceGroup{
		{
			IgnoreState: types.IncludeIgnoredTraces,
		},
		{
			IgnoreState: types.ExcludeIgnoredTraces,
		},
		{
			IgnoreState: types.IncludeIgnoredTraces,
			Corpus:      "gm",
		},
		{
			IgnoreState: types.ExcludeIgnoredTraces,
			Corpus:      "gm",
		},
		{
			IgnoreState: types.IncludeIgnoredTraces,
			Corpus:      "gm",
			Test:        data.AlphaTest,
		},
		{
			IgnoreState: types.IncludeIgnoredTraces,
			Corpus:      "gm",
			Test:        data.BetaTest,
		},
		{
			IgnoreState: types.ExcludeIgnoredTraces,
			Corpus:      "gm",
			Test:        data.AlphaTest,
		},
		{
			IgnoreState: types.ExcludeIgnoredTraces,
			Corpus:      "gm",
			Test:        data.BetaTest,
		},
	}
	for _, psg := range allCombos {
		assert.Contains(t, si.preSliced, psg)
	}
}

// TestPreSlicedTracesQuery tests that querying SlicedTraces returns the correct set of tracePairs
// from the preSliced data. This especially includes if multiple tests are in the query.
func TestPreSlicedTracesQuery(t *testing.T) {
	unittest.SmallTest(t)
	ct, _, _ := makeComplexTileWithCrosshatchIgnores()

	si := &SearchIndex{
		preSliced: map[preSliceGroup][]*tiling.TracePair{},
		cpxTile:   ct,
	}
	require.NoError(t, preSliceData(context.Background(), si))

	allTraces := si.SlicedTraces(types.IncludeIgnoredTraces, nil)
	assert.Len(t, allTraces, 6)

	withIgnores := si.SlicedTraces(types.ExcludeIgnoredTraces, nil)
	assert.Len(t, withIgnores, 4)

	justCorpus := si.SlicedTraces(types.IncludeIgnoredTraces, map[string][]string{
		types.CorpusField: {"gm"},
	})
	assert.Len(t, justCorpus, 6)

	bothTests := si.SlicedTraces(types.IncludeIgnoredTraces, map[string][]string{
		types.CorpusField:     {"gm"},
		types.PrimaryKeyField: {string(data.BetaTest), string(data.AlphaTest)},
	})
	assert.Len(t, bothTests, 6)

	oneTest := si.SlicedTraces(types.ExcludeIgnoredTraces, map[string][]string{
		types.CorpusField:     {"gm"},
		types.PrimaryKeyField: {string(data.AlphaTest)},
	})
	assert.Len(t, oneTest, 2)

	noMatches := si.SlicedTraces(types.ExcludeIgnoredTraces, map[string][]string{
		types.CorpusField:     {"nope"},
		types.PrimaryKeyField: {string(data.AlphaTest)},
	})
	assert.Empty(t, noMatches)
}

// SummarizeByGrouping tests computing summaries for a given corpus. This emulates the underlying
// call used in the byBlame handler.
func TestSummarizeByGrouping(t *testing.T) {
	unittest.SmallTest(t)
	ct, _, partialTile := makeComplexTileWithCrosshatchIgnores()
	mes := &mock_expectations.Store{}
	defer mes.AssertExpectations(t)
	mes.On("Get", testutils.AnyContext).Return(data.MakeTestExpectations(), nil)

	dc := digest_counter.New(partialTile)
	b, err := blame.New(partialTile, data.MakeTestExpectations())
	require.NoError(t, err)

	// We can leave ParamSummary blank because they are unused.
	si, err := SearchIndexForTesting(ct, [2]digest_counter.DigestCounter{dc, dc}, [2]paramsets.ParamSummary{}, mes, b)
	require.NoError(t, err)

	sums, err := si.SummarizeByGrouping(context.Background(), "gm", nil, types.ExcludeIgnoredTraces, true)
	require.NoError(t, err)
	assert.Len(t, sums, 2)
	assert.Contains(t, sums, &summary.TriageStatus{
		Name:      data.AlphaTest,
		Corpus:    "gm",
		Pos:       1,
		Neg:       0,
		Untriaged: 1,
		Num:       2,
		UntHashes: types.DigestSlice{data.AlphaUntriagedDigest},
		Blame: []blame.WeightedBlame{
			{
				Author: data.ThirdCommitAuthor,
				Prob:   1,
			},
		},
	})
	assert.Contains(t, sums, &summary.TriageStatus{
		Name:      data.BetaTest,
		Corpus:    "gm",
		Pos:       1,
		Neg:       0,
		Untriaged: 0, // this untriaged one was hidden by the ignores
		Num:       1,
		UntHashes: types.DigestSlice{},
		Blame:     []blame.WeightedBlame{},
	})
}

func TestSearchIndex_MostRecentPositiveDigest_AllDigestsIdenticalAndPositive_Success(t *testing.T) {
	unittest.SmallTest(t)

	si, traceID := makeSearchIndexWithSingleTrace(goodDigest1, goodDigest1, goodDigest1)

	digest, err := si.MostRecentPositiveDigest(context.Background(), traceID)
	require.NoError(t, err)
	assert.Equal(t, goodDigest1, digest)
}

func TestSearchIndex_MostRecentPositiveDigest_MultiplePositiveDigests_Success(t *testing.T) {
	unittest.SmallTest(t)

	si, traceID := makeSearchIndexWithSingleTrace(goodDigest1, goodDigest2, goodDigest3)

	digest, err := si.MostRecentPositiveDigest(context.Background(), traceID)
	require.NoError(t, err)
	assert.Equal(t, goodDigest3, digest)
}

func TestSearchIndex_MostRecentPositiveDigest_LastPositiveNotAtHead_Success(t *testing.T) {
	unittest.SmallTest(t)

	si, traceID := makeSearchIndexWithSingleTrace(goodDigest1, badDigest1, goodDigest2, badDigest2, untriagedDigest1, tiling.MissingDigest)

	digest, err := si.MostRecentPositiveDigest(context.Background(), traceID)
	require.NoError(t, err)
	assert.Equal(t, goodDigest2, digest)
}

func TestSearchIndex_MostRecentPositiveDigest_NoRecentPositive_ReturnsMissingDigest(t *testing.T) {
	unittest.SmallTest(t)

	si, traceID := makeSearchIndexWithSingleTrace(untriagedDigest1, tiling.MissingDigest, badDigest1, untriagedDigest2, tiling.MissingDigest, badDigest2)

	digest, err := si.MostRecentPositiveDigest(context.Background(), traceID)
	require.NoError(t, err)
	assert.Equal(t, tiling.MissingDigest, digest)
}

func TestSearchIndex_MostRecentPositiveDigest_TraceNotFound_ReturnsMissingDigest(t *testing.T) {
	unittest.SmallTest(t)

	// We will ignore the trace in the index.
	si, _ := makeSearchIndexWithSingleTrace(goodDigest1)

	// Made-up trace ID. Should not be in the index.
	const missingTraceID = ",name=missing_trace,"

	// Assert that the made-up trace ID is actually missing.
	_, ok := si.cpxTile.GetTile(types.IncludeIgnoredTraces).Traces[missingTraceID]
	require.False(t, ok)

	digest, err := si.MostRecentPositiveDigest(context.Background(), missingTraceID)
	require.NoError(t, err)
	assert.Equal(t, tiling.MissingDigest, digest)
}

func TestSearchIndex_MostRecentPositiveDigest_ExpectationsStoreFailure_ReturnsError(t *testing.T) {
	unittest.SmallTest(t)

	si, traceID := makeSearchIndexWithSingleTrace(goodDigest1)

	// Overwrite the index's expectations.Store with a faulty one.
	mes := &mock_expectations.Store{}
	mes.On("Get", testutils.AnyContext).Return(nil, errors.New("kaboom"))
	si.expectationsStore = mes

	_, err := si.MostRecentPositiveDigest(context.Background(), traceID)
	require.Error(t, err)
	assert.Contains(t, err.Error(), "kaboom")
}

const (
	// Digests to be used in conjunction with makeSearchIndexWithSingleTrace().
	goodDigest1      = types.Digest("11111111111111111111111111111111")
	goodDigest2      = types.Digest("22222222222222222222222222222222")
	goodDigest3      = types.Digest("33333333333333333333333333333333")
	badDigest1       = types.Digest("bad11111111111111111111111111111")
	badDigest2       = types.Digest("bad22222222222222222222222222222")
	untriagedDigest1 = types.Digest("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee")
	untriagedDigest2 = types.Digest("ffffffffffffffffffffffffffffffff")
)

// makeSearchIndexWithSingleTrace returns a SearchIndex comprised of a single trace with the given
// digests, and an expectations.Store with expectations for the good/badDigestN constants defined
// above.
func makeSearchIndexWithSingleTrace(digests ...types.Digest) (*SearchIndex, tiling.TraceID) {
	const device = "my_device"
	const corpus = "my_corpus"
	const testName = types.TestName("my_test")
	const extension = "png"

	// Constructed to resemble traceIDs seen in production. It shouldn't matter for these tests.
	traceID := tiling.TraceID(fmt.Sprintf(",device=%s,name=%s,source_type=%s,", device, testName, corpus))

	// Generate tile with the given digests.
	tile := &tiling.Tile{
		Traces: map[tiling.TraceID]*tiling.Trace{
			traceID: tiling.NewTrace(digests, map[string]string{
				"device":              device,
				types.PrimaryKeyField: string(testName),
				types.CorpusField:     corpus,
			}, map[string]string{
				"ext": extension,
			}),
		},
		ParamSet: map[string][]string{
			"device":              {device},
			types.PrimaryKeyField: {string(testName)},
			types.CorpusField:     {corpus},
			"ext":                 {extension},
		},
	}

	// Generate expectations for the known digests.
	var exps expectations.Expectations
	exps.Set(testName, goodDigest1, expectations.Positive)
	exps.Set(testName, goodDigest2, expectations.Positive)
	exps.Set(testName, goodDigest3, expectations.Positive)
	exps.Set(testName, badDigest1, expectations.Negative)
	exps.Set(testName, badDigest2, expectations.Negative)

	// Build mock expectations store.
	mockExpStore := &mock_expectations.Store{}
	mockExpStore.On("Get", testutils.AnyContext).Return(&exps, nil)

	// Build return value.
	searchIndex := &SearchIndex{
		searchIndexConfig: searchIndexConfig{
			expectationsStore: mockExpStore,
		},
		cpxTile: tiling.NewComplexTile(tile),
	}

	return searchIndex, traceID
}

// You may be tempted to just use a MockComplexTile here, but I was running into a race
// condition similar to https://github.com/stretchr/testify/issues/625 In essence, try
// to avoid having a mock (A) assert it was called with another mock (B) where the
// mock B is used elsewhere. There's a race because mock B is keeping track of what was
// called on it while mock A records what it was called with. Additionally, the general guidelines
// are to prefer to use the real thing instead of a mock.
func makeComplexTileWithCrosshatchIgnores() (tiling.ComplexTile, *tiling.Tile, *tiling.Tile) {
	fullTile := data.MakeTestTile()
	partialTile := data.MakeTestTile()
	delete(partialTile.Traces, data.CrosshatchAlphaTraceID)
	delete(partialTile.Traces, data.CrosshatchBetaTraceID)

	ct := tiling.NewComplexTile(fullTile)
	ct.SetIgnoreRules(partialTile, []paramtools.ParamSet{
		{
			"device": []string{"crosshatch"},
		},
	})
	return ct, fullTile, partialTile
}

func loadChangelistExpectations(masterExp *mock_expectations.Store, crs string, clExps map[string]*expectations.Expectations) {
	for clID, exp := range clExps {
		clStore := &mock_expectations.Store{}
		clStore.On("Get", testutils.AnyContext).Return(exp, nil)
		masterExp.On("ForChangelist", clID, crs).Return(clStore)
	}
}
