package testutils

import (
	"context"
	"fmt"
	"math/rand"
	"os"
	"path"
	"strings"
	"time"

	"github.com/stretchr/testify/require"
	"go.skia.org/infra/go/exec"
	"go.skia.org/infra/go/git/git_common"
	"go.skia.org/infra/go/sktest"
	"go.skia.org/infra/go/testutils"
)

// GitBuilder creates commits and branches in a git repo.
type GitBuilder struct {
	t      sktest.TestingT
	dir    string
	branch string
	git    string
	rng    *rand.Rand
}

// GitInit calls GitInitWithDefaultBranch with MainBranch.
func GitInit(t sktest.TestingT, ctx context.Context) *GitBuilder {
	tmp, err := os.MkdirTemp("", "")
	require.NoError(t, err)

	return GitInitWithDir(t, ctx, tmp, git_common.MainBranch)
}

// GitInitWithDefaultBranch creates a new git repo in a temporary directory with the
// specified default branch and returns a GitBuilder to manage it. Call Cleanup to
// remove the temporary directory. The current branch will be the main branch.
func GitInitWithDefaultBranch(t sktest.TestingT, ctx context.Context, defaultBranch string) *GitBuilder {
	tmp, err := os.MkdirTemp("", "")
	require.NoError(t, err)

	return GitInitWithDir(t, ctx, tmp, defaultBranch)
}

// GitInit creates a new git repo in the specified directory and returns a
// GitBuilder to manage it. Call Cleanup to remove the temporary directory. The
// current branch will be the main branch.
func GitInitWithDir(t sktest.TestingT, ctx context.Context, dir, defaultBranch string) *GitBuilder {
	gitExec, _, _, err := git_common.FindGit(ctx)
	require.NoError(t, err)

	g := &GitBuilder{
		t:      t,
		dir:    dir,
		branch: defaultBranch,
		git:    gitExec,
		rng:    rand.New(rand.NewSource(0)),
	}

	g.Git(ctx, "init")
	// Set the initial branch.
	//
	// It is important to set the initial branch explicitly because developer workstations might have
	// a value for Git option init.defaultBranch[1] that differs from that of the CQ bots. This can
	// cause tests that use GitBuilder to fail locally but pass on the CQ (or vice versa).
	//
	// [1] https://git-scm.com/docs/git-config#Documentation/git-config.txt-initdefaultBranch
	//
	// TODO(lovisolo): Replace with "git init --initial-branch <git_common.MainBranch>" once all
	//                 GCE instances have been upgraded to Git >= v2.28, which introduces flag
	//                 --initial-branch.
	//                 See https://github.com/git/git/commit/32ba12dab2acf1ad11836a627956d1473f6b851a.
	g.Git(ctx, "symbolic-ref", "HEAD", "refs/heads/"+g.branch)
	g.Git(ctx, "remote", "add", git_common.DefaultRemote, ".")
	g.Git(ctx, "config", "--local", "user.name", "test")
	g.Git(ctx, "config", "--local", "user.email", "test@google.com")
	return g
}

// Cleanup removes the directory containing the git repo.
func (g *GitBuilder) Cleanup() {
	testutils.RemoveAll(g.t, g.dir)
}

// Dir returns the directory of the git repo, e.g. for cloning.
func (g *GitBuilder) Dir() string {
	return g.dir
}

// RepoUrl returns a git-friendly URL for the repo.
func (g *GitBuilder) RepoUrl() string {
	return fmt.Sprintf("file://%s", g.Dir())
}

// Seed replaces the random seed used by the GitBuilder.
func (g *GitBuilder) Seed(seed int64) {
	g.rng.Seed(seed)
}

func (g *GitBuilder) Git(ctx context.Context, cmd ...string) string {
	output, err := exec.RunCwd(ctx, g.dir, append([]string{g.git}, cmd...)...)
	require.NoError(g.t, err)
	return output
}

func (g *GitBuilder) runCommand(ctx context.Context, cmd *exec.Command) string {
	cmd.InheritEnv = true
	cmd.Dir = g.dir
	output, err := exec.RunCommand(ctx, cmd)
	require.NoError(g.t, err)
	return output
}

func (g *GitBuilder) write(filepath, contents string) {
	fullPath := path.Join(g.dir, filepath)
	dir := path.Dir(fullPath)
	if dir != "" {
		require.NoError(g.t, os.MkdirAll(dir, os.ModePerm))
	}
	require.NoError(g.t, os.WriteFile(fullPath, []byte(contents), os.ModePerm))
}

func (g *GitBuilder) push(ctx context.Context) {
	g.Git(ctx, "push", git_common.DefaultRemote, g.branch)
}

// genString returns a string with arbitrary content.
func (g *GitBuilder) genString() string {
	return fmt.Sprintf("%d", g.rng.Int())
}

// Add writes contents to file and adds it to the index.
func (g *GitBuilder) Add(ctx context.Context, file, contents string) {
	g.write(file, contents)
	g.Git(ctx, "add", file)
}

// AddGen writes arbitrary content to file and adds it to the index.
func (g *GitBuilder) AddGen(ctx context.Context, file string) {
	g.Add(ctx, file, g.genString())
}

func (g *GitBuilder) lastCommitHash(ctx context.Context) string {
	return strings.TrimSpace(g.Git(ctx, "rev-parse", "HEAD"))
}

// CommitMsg commits files in the index with the given commit message using the
// given time as the commit time. The current branch is then pushed.
// Note that the nanosecond component of time will be dropped. Returns the hash
// of the new commit.
func (g *GitBuilder) CommitMsgAt(ctx context.Context, msg string, time time.Time) string {
	g.runCommand(ctx, &exec.Command{
		Name: g.git,
		Args: []string{"commit", "-m", msg},
		Env:  []string{fmt.Sprintf("GIT_AUTHOR_DATE=%d +0000", time.Unix()), fmt.Sprintf("GIT_COMMITTER_DATE=%d +0000", time.Unix())},
	})
	g.push(ctx)
	return g.lastCommitHash(ctx)
}

// CommitMsg commits files in the index with the given commit message. The
// current branch is then pushed. Returns the hash of the new commit.
func (g *GitBuilder) CommitMsg(ctx context.Context, msg string) string {
	return g.CommitMsgAt(ctx, msg, time.Now())
}

// Commit commits files in the index. The current branch is then pushed. Uses an
// arbitrary commit message. Returns the hash of the new commit.
func (g *GitBuilder) Commit(ctx context.Context) string {
	return g.CommitMsg(ctx, g.genString())
}

// CommitGen commits arbitrary content to the given file. The current branch is
// then pushed. Returns the hash of the new commit.
func (g *GitBuilder) CommitGen(ctx context.Context, file string) string {
	s := g.genString()
	g.Add(ctx, file, s)
	return g.CommitMsg(ctx, s)
}

// CommitGenAt commits arbitrary content to the given file using the given time
// as the commit time. Note that the nanosecond component of time will be
// dropped. Returns the hash of the new commit.
func (g *GitBuilder) CommitGenAt(ctx context.Context, file string, ts time.Time) string {
	g.AddGen(ctx, file)
	return g.CommitMsgAt(ctx, g.genString(), ts)
}

// CommitGenMsg commits arbitrary content to the given file and uses the given
// commit message. The current branch is then pushed. Returns the hash of the
// new commit.
func (g *GitBuilder) CommitGenMsg(ctx context.Context, file, msg string) string {
	g.AddGen(ctx, file)
	return g.CommitMsg(ctx, msg)
}

// CreateBranchTrackBranch creates a new branch tracking an existing branch,
// checks out the new branch, and pushes the new branch.
func (g *GitBuilder) CreateBranchTrackBranch(ctx context.Context, newBranch, existingBranch string) {
	g.Git(ctx, "checkout", "-b", newBranch, "-t", existingBranch)
	g.branch = newBranch
	g.push(ctx)
}

// CreateBranchTrackBranch creates a new branch pointing at the given commit,
// checks out the new branch, and pushes the new branch.
func (g *GitBuilder) CreateBranchAtCommit(ctx context.Context, name, commit string) {
	g.Git(ctx, "checkout", "--no-track", "-b", name, commit)
	g.branch = name
	g.push(ctx)
}

// CreateOrphanBranch creates a new orphan branch.
func (g *GitBuilder) CreateOrphanBranch(ctx context.Context, newBranch string) {
	g.Git(ctx, "checkout", "--orphan", newBranch)
	g.branch = newBranch
	// Can't push, since the branch doesn't currently point to any commit.
}

// CheckoutBranch checks out the given branch.
func (g *GitBuilder) CheckoutBranch(ctx context.Context, name string) {
	g.Git(ctx, "checkout", name)
	g.branch = name
}

// MergeBranchAt merges the given branch into the current branch at the given
// time and pushes the current branch. Returns the hash of the new commit.
func (g *GitBuilder) MergeBranchAt(ctx context.Context, name string, ts time.Time) string {
	require.NotEqual(g.t, g.branch, name, "Can't merge a branch into itself.")
	args := []string{"merge", name}
	_, major, minor, err := git_common.FindGit(ctx)
	require.NoError(g.t, err)
	if (major == 2 && minor >= 9) || major > 2 {
		args = append(args, "--allow-unrelated-histories")
	}
	g.runCommand(ctx, &exec.Command{
		Name: g.git,
		Args: args,
		Env:  []string{fmt.Sprintf("GIT_AUTHOR_DATE=%d +0000", ts.Unix()), fmt.Sprintf("GIT_COMMITTER_DATE=%d +0000", ts.Unix())},
	})
	g.push(ctx)
	return g.lastCommitHash(ctx)
}

// MergeBranch merges the given branch into the current branch and pushes the
// current branch. Returns the hash of the new commit.
func (g *GitBuilder) MergeBranch(ctx context.Context, name string) string {
	return g.MergeBranchAt(ctx, name, time.Now())
}

// Reset runs "git reset" in the repo.
func (g *GitBuilder) Reset(ctx context.Context, args ...string) {
	cmd := append([]string{"reset"}, args...)
	g.Git(ctx, cmd...)
	g.push(ctx)
}

// UpdateRef runs "git update-ref" in the repo.
func (g *GitBuilder) UpdateRef(ctx context.Context, args ...string) {
	cmd := append([]string{"update-ref"}, args...)
	g.Git(ctx, cmd...)
	g.push(ctx)
}

// CreateFakeGerritCLGen creates a Gerrit-like ref so that it can be applied like
// a CL on a trybot.
func (g *GitBuilder) CreateFakeGerritCLGen(ctx context.Context, issue, patchset string) {
	currentBranch := strings.TrimSpace(g.Git(ctx, "rev-parse", "--abbrev-ref", "HEAD"))
	g.CreateBranchTrackBranch(ctx, "fake-patch", git_common.MainBranch)
	patchCommit := g.CommitGen(ctx, "somefile")
	g.UpdateRef(ctx, fmt.Sprintf("refs/changes/%s/%s/%s", issue[len(issue)-2:], issue, patchset), patchCommit)
	g.CheckoutBranch(ctx, currentBranch)
	g.Git(ctx, "branch", "-D", "fake-patch")
}

// AcceptPushes allows pushing changes to the repo.
func (g *GitBuilder) AcceptPushes(ctx context.Context) {
	// TODO(lovisolo): Consider making GitBuilder point to a bare repository (git init --bare).
	// Under this scenario, GitBuilder would push to that bare repository, and GitBuilder.RepoUrl()
	// would return the URL for the bare repository. This would remove the need for this method.

	g.Git(ctx, "config", "receive.denyCurrentBranch", "ignore")
}

// GitSetup adds commits to the Git repo managed by g.
//
// The repo layout looks like this:
//
// older           newer
// c0--c1------c3--c4--
//
//	\-c2-----/
//
// Returns the commit hashes in order from c0-c4.
func GitSetup(ctx context.Context, g *GitBuilder) []string {
	c0 := g.CommitGen(ctx, "myfile.txt")
	c1 := g.CommitGen(ctx, "myfile.txt")
	g.CreateBranchTrackBranch(ctx, "branch2", git_common.DefaultRemoteBranch)
	c2 := g.CommitGen(ctx, "anotherfile.txt")
	g.CheckoutBranch(ctx, git_common.MainBranch)
	c3 := g.CommitGen(ctx, "myfile.txt")
	c4 := g.MergeBranch(ctx, "branch2")
	return []string{c0, c1, c2, c3, c4}
}
