package bt_gitstore_test

import (
	"context"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"sort"
	"testing"

	"github.com/stretchr/testify/require"
	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/git"
	"go.skia.org/infra/go/git/gitinfo"
	"go.skia.org/infra/go/gitstore"
	gitstore_testutils "go.skia.org/infra/go/gitstore/testutils"
	"go.skia.org/infra/go/testutils/unittest"
	"go.skia.org/infra/go/timer"
	"go.skia.org/infra/go/util"
	"go.skia.org/infra/go/vcsinfo"
	vcs_testutils "go.skia.org/infra/go/vcsinfo/testutils"
)

const (
	localRepoURL = "https://example.com/local.git"
)

// This test uses a checkout of a repo (can be really any repo) in /tmp/skia.
// If not present, syncs skia.git to /tmp/skia first.
func TestGitStoreSkiaRepo(t *testing.T) {
	unittest.ManualTest(t)
	t.Skip()
	skiaRepoDir := filepath.Join(os.TempDir(), "skia")
	if _, err := os.Stat(skiaRepoDir); os.IsNotExist(err) {
		_, err = git.NewRepo(context.Background(), common.REPO_SKIA, os.TempDir())
		require.NoError(t, err)
	} else if err != nil {
		require.FailNow(t, err.Error())
	}
	testGitStore(t, common.REPO_SKIA, skiaRepoDir, true)
}

func TestGitStoreLocalRepo(t *testing.T) {
	unittest.LargeTest(t)

	repoDir, cleanup := vcs_testutils.InitTempRepo()
	defer cleanup()
	testGitStore(t, "file://"+repoDir, repoDir, true)
}

func testGitStore(t *testing.T, repoURL, repoDir string, freshLoad bool) {
	wd, err := ioutil.TempDir("", "")
	require.NoError(t, err)
	defer util.RemoveAll(wd)

	// Get all commits that have been added to the gitstore.
	_, longCommits, gitStore := gitstore_testutils.SetupAndLoadBTGitStore(t, context.Background(), wd, repoURL, freshLoad)

	// Sort long commits they way they are sorted by BigTable (by timestamp/hash)
	sort.Slice(longCommits, func(i, j int) bool {
		tsI := longCommits[i].Timestamp.Unix()
		tsJ := longCommits[j].Timestamp.Unix()
		return (tsI < tsJ) || ((tsI == tsJ) && (longCommits[i].Hash < longCommits[j].Hash))
	})
	indexCommits := make([]*vcsinfo.IndexCommit, len(longCommits))
	for idx, commit := range longCommits {
		indexCommits[idx] = &vcsinfo.IndexCommit{
			Index:     idx,
			Hash:      commit.Hash,
			Timestamp: commit.Timestamp,
		}
	}

	// Find all the commits in the repository independent of branches.
	foundIndexCommits, foundLongCommits := getFromRange(t, gitStore, 0, len(longCommits), gitstore.ALL_BRANCHES)
	require.Equal(t, len(indexCommits), len(foundIndexCommits))
	require.Equal(t, len(longCommits), len(foundLongCommits))

	// Make sure they match what we found.
	for idx, expected := range longCommits {
		foundLongCommits[idx].Branches = expected.Branches
		require.Equal(t, expected, foundLongCommits[idx])
	}

	// Verify that the branches from the GitStore match what's in the checkout.
	branchNames, branchCommits := getBranchCommits(t, repoDir)
	for branchIdx, branchName := range branchNames {
		expHashes := branchCommits[branchIdx]
		foundIndexCommits, foundLongCommits := getFromRange(t, gitStore, 0, len(longCommits), branchName)
		require.Equal(t, len(expHashes), len(foundIndexCommits))
		require.Equal(t, len(expHashes), len(foundLongCommits))
		expIdx := len(expHashes) - 1
		for idx := len(foundIndexCommits) - 1; idx >= 0; idx-- {
			expHash := expHashes[expIdx]
			require.Equal(t, foundIndexCommits[idx].Hash, foundLongCommits[idx].Hash)
			require.Equal(t, expHash, foundIndexCommits[idx].Hash)
			expIdx--
		}
	}
}

func getBranchCommits(t *testing.T, repoDir string) ([]string, [][]string) {
	ctx := context.TODO()
	vcs, err := gitinfo.NewGitInfo(ctx, repoDir, false, true)
	require.NoError(t, err)

	branches, err := vcs.GetBranches(ctx)
	require.NoError(t, err)

	branchNames := make([]string, 0, len(branches))
	branchCommits := make([][]string, 0, len(branches))
	for _, branch := range branches {
		// if strings.Contains(branch.Name, "m62") {
		// 	continue
		// }
		branchNames = append(branchNames, branch.Name)
		indexCommits, err := gitinfo.GetBranchCommits(ctx, repoDir, branch.Name)
		require.NoError(t, err)
		commitHashes := make([]string, len(indexCommits))
		for idx, idxCommit := range indexCommits {
			commitHashes[idx] = idxCommit.Hash
		}
		branchCommits = append(branchCommits, commitHashes)
	}

	return branchNames, branchCommits
}

func getFromRange(t *testing.T, gitStore gitstore.GitStore, startIdx, endIdx int, branchName string) ([]*vcsinfo.IndexCommit, []*vcsinfo.LongCommit) {
	ctx := context.TODO()

	tQuery := timer.New(fmt.Sprintf("RangeN %d - %d commits from branch %q", startIdx, endIdx, branchName))
	foundIndexCommits, err := gitStore.RangeN(ctx, startIdx, endIdx, branchName)
	require.NoError(t, err)
	tQuery.Stop()

	hashes := make([]string, 0, len(foundIndexCommits))
	for _, commit := range foundIndexCommits {
		hashes = append(hashes, commit.Hash)
	}
	tLongCommits := timer.New(fmt.Sprintf("Get %d LongCommits from branch %q", len(hashes), branchName))
	foundLongCommits, err := gitStore.Get(ctx, hashes)
	require.NoError(t, err)
	require.Equal(t, len(foundIndexCommits), len(foundLongCommits))
	tLongCommits.Stop()

	return foundIndexCommits, foundLongCommits
}
