package main

import (
	"context"
	"flag"
	"fmt"

	"go.skia.org/infra/go/common"
	"go.skia.org/infra/go/git"
	"go.skia.org/infra/go/gitstore"
	"go.skia.org/infra/go/gitstore/bt_gitstore"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/timer"
)

// btgit is a script that queries a BigTable based GitStore.

func main() {
	// Define the flags and parse them.
	var (
		btInstanceID = flag.String("bt_instance", "production", "Big Table instance")
		btTableID    = flag.String("bt_table", "git-repos", "BigTable table ID")
		listBranches = flag.Bool("list", false, "List all branches and quit")
		listRepos    = flag.Bool("list_repos", false, "List all repositories quit")
		loadGraph    = flag.Bool("load_graph", false, "Load the entire commit graph. For performance check only.")
		projectID    = flag.String("project", "skia-public", "ID of the GCP project")
		branch       = flag.String("branch", gitstore.ALL_BRANCHES, "Name of the branch to list. By default, show all commits across all branches.")
		limit        = flag.Int("limit", 100, "Number of commits to show. 0 means no limit")
		repoURL      = flag.String("repo_url", "", "URL of the git repo.")
		verbose      = flag.Bool("verbose", false, "Indicate whether to log the commits we find.")
	)
	common.Init()

	// Configure the bigtable instance.
	config := &bt_gitstore.BTConfig{
		ProjectID:  *projectID,
		InstanceID: *btInstanceID,
		TableID:    *btTableID,
		AppProfile: "btgit",
	}

	// Normalize the URL as GitStore does.
	normURL, err := git.NormalizeURL(*repoURL)
	if err != nil {
		sklog.Fatalf("Error getting normalized URL for %s:  %s", *repoURL, err)
	}

	ctx := context.Background()

	// Get all repos and find the one we want plus the branch we want.
	allRepoInfos, err := bt_gitstore.AllRepos(ctx, config)
	if err != nil {
		sklog.Fatalf("Error retrieving lists of repositories: %s", err)
	}
	sklog.Infof("Got all repo info: %d", len(allRepoInfos))

	if *listRepos {
		for _, repo := range allRepoInfos {
			fmt.Printf("Repo: %s \n", repo.RepoURL)
			if *verbose {
				logBranches("    ", repo.Branches)
			}
		}
		return
	}

	// Make sure our repoURL exists.
	repoInfo, ok := allRepoInfos[normURL]
	if !ok {
		sklog.Fatalf("Repo %s could not found in BigTable", normURL)
	}
	sklog.Infof("Found repo for %s", repoInfo.RepoURL)

	if *listBranches {
		logBranches("", repoInfo.Branches)
		return
	}

	// Make sure the target branch exists
	foundBranch, ok := repoInfo.Branches[*branch]
	if !ok {
		sklog.Fatalf("Error, branch %q does not exist in BigTable git", *branch)
	}
	sklog.Infof("Found branch %q in repo for %s", *branch, repoInfo.RepoURL)

	// Create a new BT based GitStore.
	gitStore, err := bt_gitstore.New(ctx, config, *repoURL)
	if err != nil {
		sklog.Fatalf("Error instantiating git store: %s", err)
	}
	sklog.Infof("Opened gitstore")

	// Determine how many commits we fetch.
	startIndex := 0
	branchLength := foundBranch.Index + 1
	if *limit > 0 {
		startIndex = branchLength - *limit
	}

	// Fetch the graph of the repository to see if it performs well enough.
	if *loadGraph {
		ggt := timer.New("Getting graph")
		commitGraph, err := gitstore.GetRepoGraph(ctx, gitStore)
		if err != nil {
			sklog.Fatalf("Error retrieving graph: %s", err)
		}
		ggt.Stop()
		sklog.Infof("Loaded graph with %d nodes", commitGraph.Len())
	}

	// Retrieve the index commits we are interested in.
	indexCommits, err := gitStore.RangeN(ctx, startIndex, branchLength, *branch)
	if err != nil {
		sklog.Fatalf("Error retrieving branch %q: %s", *branch, err)
	}

	// Isolate the hashes and retrieve the LongCommits.
	hashes := make([]string, 0, len(indexCommits))
	for _, commit := range indexCommits {
		hashes = append(hashes, commit.Hash)
	}

	tlc := timer.New("Long commits")
	longCommits, err := gitStore.Get(ctx, hashes)
	if err != nil {
		sklog.Fatalf("Error retrieving long commits: %s", err)
	}
	tlc.Stop()
	sklog.Infof("Long commits loaded: %d", len(longCommits))

	for idx := len(longCommits) - 1; idx >= 0; idx-- {
		c := longCommits[idx]
		if c == nil {
			sklog.Fatalf("Programming error: Unable to retrieve long commit for hash %s", hashes[idx])
		}
		if *verbose {
			fmt.Printf("%s %40s %v %s\n", c.Hash, c.Author, c.Timestamp, c.Subject)
		}
	}
}

func logBranches(indent string, branches map[string]*gitstore.BranchPointer) {
	for branchName, branch := range branches {
		fmt.Printf("Branch %s @ %s with index %d\n", branchName, branch.Head, branch.Index)
	}
}
