package bt_vcs

import (
	"context"
	"io/ioutil"
	"math"
	"testing"
	"time"

	"github.com/stretchr/testify/require"
	"go.skia.org/infra/go/git"
	"go.skia.org/infra/go/gitstore"
	gs_testutils "go.skia.org/infra/go/gitstore/bt_gitstore/testutils"
	"go.skia.org/infra/go/gitstore/mocks"
	"go.skia.org/infra/go/testutils"
	"go.skia.org/infra/go/util"
	"go.skia.org/infra/go/vcsinfo"
	vcs_testutils "go.skia.org/infra/go/vcsinfo/testutils"
	"golang.org/x/sync/errgroup"
)

func TestVCSSuite(t *testing.T) {
	vcs, _, cleanup := setupVCSLocalRepo(t, git.MasterBranch)
	defer cleanup()

	// Run the VCS test suite.
	vcs_testutils.TestByIndex(t, vcs)
	vcs_testutils.TestDisplay(t, vcs)
	vcs_testutils.TestFrom(t, vcs)
	vcs_testutils.TestIndexOf(t, vcs)
	vcs_testutils.TestLastNIndex(t, vcs)
	vcs_testutils.TestRange(t, vcs)
}

func TestBranchInfo(t *testing.T) {
	vcs, gitStore, cleanup := setupVCSLocalRepo(t, gitstore.ALL_BRANCHES)
	defer cleanup()

	branchPointers, err := gitStore.GetBranches(context.Background())
	require.NoError(t, err)
	branches := []string{}
	for branchName := range branchPointers {
		if branchName != gitstore.ALL_BRANCHES {
			branches = append(branches, branchName)
		}
	}

	vcs_testutils.TestBranchInfo(t, vcs, branches)
}

// TestConcurrentUpdate verifies that BigTableVCS.Update() behaves correctly
// when called concurrently.
func TestConcurrentUpdate(t *testing.T) {

	numGoroutines := 10
	mg := &mocks.GitStore{}
	defer mg.AssertExpectations(t)

	// Pretend the repo has one commit at first.
	ics := makeTestIndexCommits()
	lcs := makeTestLongCommits()
	hashes := make([]string, 0, len(ics))
	for _, ic := range ics {
		hashes = append(hashes, ic.Hash)
	}

	mg.On("RangeN", testutils.AnyContext, 0, math.MaxInt32, git.MasterBranch).Return(ics[:1], nil).Once()
	mg.On("Get", testutils.AnyContext, hashes[:1]).Return(lcs[:1], nil).Once()

	ctx := context.Background()
	vcs, err := New(ctx, mg, git.MasterBranch)
	require.NoError(t, err)

	// Now, pretend that the other two commits have landed, and run Update
	// in several goroutines. We expect the first call to Update() to run
	// RangeN starting at zero (despite our already having the first commit
	// from above, because we request a range which overlaps by one commit.
	// Subsequent calls should already be loaded with IndexCommits and thus
	// should start at 2.
	mg.On("RangeN", testutils.AnyContext, 0, math.MaxInt32, git.MasterBranch).Return(ics, nil).Once()
	mg.On("Get", testutils.AnyContext, hashes[1:]).Return(lcs[1:], nil).Once()
	mg.On("RangeN", testutils.AnyContext, 2, math.MaxInt32, git.MasterBranch).Return(ics[2:], nil)

	var egroup errgroup.Group
	for i := 0; i < numGoroutines; i++ {
		egroup.Go(func() error {
			return vcs.Update(ctx, true, false)
		})
	}
	require.NoError(t, egroup.Wait())
}

// TestDetailsCaching makes sure that multiple calls to Details do
// not result in multiple calls to the underlying gitstore, that is,
// the details per commit hash are cached.
func TestDetailsCaching(t *testing.T) {

	mg := &mocks.GitStore{}
	defer mg.AssertExpectations(t)

	commits := makeTestLongCommits()

	mg.On("RangeN", testutils.AnyContext, 0, math.MaxInt32, git.MasterBranch).Return(makeTestIndexCommits(), nil)
	mg.On("Get", testutils.AnyContext, []string{firstHash, secondHash, thirdHash}).Return(commits, nil).Once()

	vcs, err := New(context.Background(), mg, git.MasterBranch)
	require.NoError(t, err)

	// query details 3 times, and make sure it uses the cache after the
	// first time. Since we said Once() on the mocked Get function, we are
	// assured that gitstore.Get() is only called once.
	ctx := context.Background()
	c, err := vcs.Details(ctx, firstHash, false)
	require.NoError(t, err)
	require.Equal(t, commits[0], c)
	require.Nil(t, c.Branches)
	c, err = vcs.Details(ctx, firstHash, false)
	require.NoError(t, err)
	require.Equal(t, commits[0], c)
	c, err = vcs.Details(ctx, firstHash, false)
	require.NoError(t, err)
	require.Equal(t, commits[0], c)
}

// TestDetailsMultiCaching makes sure that multiple calls to DetailsMulti do
// not result in multiple calls to the underlying gitstore, that is,
// the details per commit hash are cached.
func TestDetailsMultiCaching(t *testing.T) {

	mg := &mocks.GitStore{}
	defer mg.AssertExpectations(t)

	commits := makeTestLongCommits()

	mg.On("RangeN", testutils.AnyContext, 0, math.MaxInt32, git.MasterBranch).Return(makeTestIndexCommits(), nil)
	mg.On("Get", testutils.AnyContext, []string{firstHash, secondHash, thirdHash}).Return(commits, nil).Once()

	vcs, err := New(context.Background(), mg, git.MasterBranch)
	require.NoError(t, err)

	// query details 3 times, and make sure it uses the cache after the
	// first time. Since we said Once() on the mocked Get function, we are
	// assured that gitstore.Get() is only called once.
	ctx := context.Background()
	c, err := vcs.DetailsMulti(ctx, []string{firstHash, secondHash}, false)
	require.NoError(t, err)
	require.NotNil(t, c)
	require.Len(t, c, 2)
	require.Equal(t, commits[0], c[0])
	require.Equal(t, commits[1], c[1])
	c, err = vcs.DetailsMulti(ctx, []string{firstHash, secondHash}, false)
	require.NoError(t, err)
	require.NotNil(t, c)
	require.Len(t, c, 2)
	require.Equal(t, commits[0], c[0])
	require.Equal(t, commits[1], c[1])
	c, err = vcs.DetailsMulti(ctx, []string{firstHash, secondHash}, false)
	require.NoError(t, err)
	require.NotNil(t, c)
	require.Len(t, c, 2)
	require.Equal(t, commits[0], c[0])
	require.Equal(t, commits[1], c[1])
}

// setupVCSLocalRepo loads the test repo into a new GitStore and returns an instance of vcsinfo.VCS.
func setupVCSLocalRepo(t *testing.T, branch string) (vcsinfo.VCS, gitstore.GitStore, func()) {
	repoDir, cleanup := vcs_testutils.InitTempRepo(t)
	wd, err := ioutil.TempDir("", "")
	require.NoError(t, err)
	ctx := context.Background()
	_, _, btgs := gs_testutils.SetupAndLoadBTGitStore(t, ctx, wd, "file://"+repoDir, true)
	vcs, err := New(ctx, btgs, branch)
	require.NoError(t, err)
	return vcs, btgs, func() {
		util.RemoveAll(wd)
		cleanup()
	}
}

const (
	// arbitrary sha1 hashes
	firstHash  = "ae76331b95dfc399cd776d2fc68021e0db03cc4f"
	secondHash = "b295e0bdde1938d1fbfd343e5a3e569e868e1465"
	thirdHash  = "cf70f4c33de2200b76651bbe1e54aa55fcd77447"
)

var (
	// arbitrary times
	firstTime  = time.Date(2019, time.May, 2, 12, 0, 3, 0, time.UTC)
	secondTime = time.Date(2019, time.May, 2, 14, 1, 3, 0, time.UTC)
	thirdTime  = time.Date(2019, time.May, 2, 17, 5, 3, 0, time.UTC)
)

// This test data (for a repo of 3 commits) is returned via functions
// to make it convenient to have a copy of the data for each test,
// so the tests can write all over the returned values w/o impacting
// tests that follow.
func makeTestLongCommits() []*vcsinfo.LongCommit {
	return []*vcsinfo.LongCommit{
		{
			ShortCommit: &vcsinfo.ShortCommit{
				Author:  "alpha@example.com",
				Hash:    firstHash,
				Subject: "initial commit",
			},
			Body:      "awesome message",
			Parents:   []string{},
			Timestamp: firstTime,
		},
		{
			ShortCommit: &vcsinfo.ShortCommit{
				Author:  "beta@example.com",
				Hash:    secondHash,
				Subject: "followup commit",
			},
			Body:      "bug fixes",
			Parents:   []string{firstHash},
			Timestamp: secondTime,
		},
		{
			ShortCommit: &vcsinfo.ShortCommit{
				Author:  "gamma@example.com",
				Hash:    thirdHash,
				Subject: "last commit",
			},
			Body:      "now deprecated",
			Parents:   []string{secondHash},
			Timestamp: thirdTime,
		},
	}
}

func makeTestIndexCommits() []*vcsinfo.IndexCommit {
	return []*vcsinfo.IndexCommit{
		{
			Hash:      firstHash,
			Index:     0,
			Timestamp: firstTime,
		},
		{
			Hash:      secondHash,
			Index:     1,
			Timestamp: secondTime,
		},
		{
			Hash:      thirdHash,
			Index:     2,
			Timestamp: thirdTime,
		},
	}
}
