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/now"
	"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.Executable(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, now.Now(ctx))
}

// 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.Version(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, now.Now(ctx))
}

// 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}
}
