package git

import (
	"context"
	"fmt"
	"os"
	"path/filepath"
	"strings"

	"go.skia.org/infra/go/exec"
	"go.skia.org/infra/go/skerr"
	"go.skia.org/infra/go/sklog"
	"go.skia.org/infra/go/vcsinfo"
)

/*
	Utility for managing a Git checkout.
*/

// Checkout is used for managing a local git checkout.
type Checkout interface {
	GitDir

	// FetchRefFromRepo syncs the specified ref from the repo without modifying the
	// working copy.
	FetchRefFromRepo(ctx context.Context, repo, ref string) error

	// Fetch syncs refs from the remote without modifying the working copy.
	Fetch(ctx context.Context) error

	// AddRemote checks to see if a remote already exists in the checkout, if it
	// exists then the URL is matched with the repoURL. If the remote does not exist
	// then it is added.
	AddRemote(ctx context.Context, remote, repoUrl string) error

	// CleanupBranch forcibly resets all changes and checks out the given branch,
	// forcing it to match the same branch from origin. All local changes will be
	// lost.
	CleanupBranch(ctx context.Context, branch string) error

	// Cleanup forcibly resets all changes and checks out the main branch to match
	// that of the remote. All local changes will be lost.
	Cleanup(ctx context.Context) error

	// UpdateBranch syncs the Checkout from its remote. Forcibly resets and checks
	// out the given branch, forcing it to match the same branch from origin. All
	// local changes will be lost. Equivalent to c.Fetch() + c.CleanupBranch().
	UpdateBranch(ctx context.Context, branch string) error

	// Update syncs the Checkout from its remote. Forcibly resets and checks out
	// the main branch to match the remote. All local changes will be lost.
	// Equivalent to c.Fetch() + c.Cleanup().
	Update(ctx context.Context) error

	// IsDirty returns true if the Checkout is dirty, ie. any of the following are
	// true:
	// 1. There are unstaged changes.
	// 2. There are untracked files (not including .gitignore'd files).
	// 3. HEAD is not an ancestor of origin/main.
	//
	// Also returns the output of "git status", for human consumption if desired.
	IsDirty(ctx context.Context) (bool, string, error)
}

// CheckoutDir implements Checkout.
type CheckoutDir string

// NewCheckout returns a Checkout instance based in the given working directory.
// Uses any existing checkout in the given directory, or clones one if
// necessary. In general, servers should use Repo instead of Checkout unless it
// is absolutely necessary to have a working copy.
func NewCheckout(ctx context.Context, repoUrl, workdir string) (CheckoutDir, error) {
	g, err := newGitDir(ctx, repoUrl, workdir, false)
	if err != nil {
		return "", skerr.Wrap(err)
	}
	return CheckoutDir(g), nil
}

// Dir returns the working directory of the GitDir.
func (c CheckoutDir) Dir() string {
	return string(c)
}

// Git runs the given git command in the Checkout.
func (c CheckoutDir) Git(ctx context.Context, cmd ...string) (string, error) {
	git, err := Executable(ctx)
	if err != nil {
		return "", skerr.Wrap(err)
	}
	baseCmd := []string{git}
	return exec.RunCwd(ctx, c.Dir(), append(baseCmd, cmd...)...)
}

// FetchRefFromRepo syncs the specified ref from the repo without modifying the
// working copy.
func (c CheckoutDir) FetchRefFromRepo(ctx context.Context, repo, ref string) error {
	_, err := c.Git(ctx, "fetch", repo, ref)
	return skerr.Wrap(err)
}

// Fetch syncs refs from the remote without modifying the working copy.
func (c CheckoutDir) Fetch(ctx context.Context) error {
	_, err := c.Git(ctx, "fetch", "--prune", DefaultRemote)
	return skerr.Wrap(err)
}

// AddRemote checks to see if a remote already exists in the checkout, if it
// exists then the URL is matched with the repoURL. If the remote does not exist
// then it is added.
func (c CheckoutDir) AddRemote(ctx context.Context, remote, repoUrl string) error {
	// Check to see whether there is an upstream yet.
	remoteOutput, err := c.Git(ctx, "remote", "get-url", remote)
	if err != nil {
		if strings.Contains(err.Error(), "No such remote") {
			if _, err := c.Git(ctx, "remote", "add", remote, repoUrl); err != nil {
				return skerr.Wrap(err)
			}
		} else {
			return skerr.Wrap(err)
		}
	} else {
		// Remote already exists. Make sure that the URLs match.
		if strings.TrimSpace(remoteOutput) != repoUrl {
			return skerr.Fmt("%s points to %s instead of %s", remote, strings.TrimSpace(remoteOutput), repoUrl)
		}
	}
	return nil
}

// CleanupBranch forcibly resets all changes and checks out the given branch,
// forcing it to match the same branch from origin. All local changes will be
// lost.
func (c CheckoutDir) CleanupBranch(ctx context.Context, branch string) error {
	if _, err := c.Git(ctx, "checkout", "-f", "-B", branch, "-t", fmt.Sprintf("origin/%s", branch)); err != nil {
		return skerr.Wrap(err)
	}
	if _, err := c.Git(ctx, "clean", "-d", "-f"); err != nil {
		return skerr.Wrap(err)
	}
	if _, err := c.Git(ctx, "reset", "--hard", fmt.Sprintf("origin/%s", branch)); err != nil {
		return skerr.Wrap(err)
	}
	return nil
}

// Cleanup forcibly resets all changes and checks out the main branch to match
// that of the remote. All local changes will be lost.
func (c CheckoutDir) Cleanup(ctx context.Context) error {
	return c.CleanupBranch(ctx, MainBranch)
}

// UpdateBranch syncs the Checkout from its remote. Forcibly resets and checks
// out the given branch, forcing it to match the same branch from origin. All
// local changes will be lost. Equivalent to c.Fetch() + c.CleanupBranch().
func (c CheckoutDir) UpdateBranch(ctx context.Context, branch string) error {
	if err := c.Fetch(ctx); err != nil {
		return skerr.Wrap(err)
	}
	if err := c.CleanupBranch(ctx, branch); err != nil {
		return skerr.Wrap(err)
	}
	return nil
}

// Update syncs the Checkout from its remote. Forcibly resets and checks out
// the main branch to match the remote. All local changes will be lost.
// Equivalent to c.Fetch() + c.Cleanup().
func (c CheckoutDir) Update(ctx context.Context) error {
	return c.UpdateBranch(ctx, MainBranch)
}

// IsDirty returns true if the Checkout is dirty, ie. any of the following are
// true:
// 1. There are unstaged changes.
// 2. There are untracked files (not including .gitignore'd files).
// 3. HEAD is not an ancestor of origin/main.
//
// Also returns the output of "git status", for human consumption if desired.
func (c CheckoutDir) IsDirty(ctx context.Context) (bool, string, error) {
	status, err := c.Git(ctx, "status")
	if err != nil {
		return false, "", skerr.Wrap(err)
	}
	if _, err := c.Git(ctx, "update-index", "--refresh"); err != nil {
		return true, status, nil
	}
	if _, err := c.Git(ctx, "diff-index", "--quiet", "HEAD", "--"); err != nil {
		return true, status, nil
	}
	output, err := c.Git(ctx, "ls-files", "--other", "--directory", "--exclude-standard")
	if err != nil {
		return false, status, skerr.Wrap(err)
	}
	output = strings.TrimSpace(output)
	if output != "" {
		return true, status, nil
	}
	if anc, err := c.IsAncestor(ctx, "HEAD", DefaultRemoteBranch); err != nil {
		return false, status, skerr.Wrap(err)
	} else if !anc {
		return true, status, nil
	}
	return false, status, nil
}

// Details returns a vcsinfo.LongCommit instance representing the given commit.
func (c CheckoutDir) Details(ctx context.Context, name string) (*vcsinfo.LongCommit, error) {
	return gitRunner_Details(ctx, c, name)
}

// RevParse runs "git rev-parse <name>" and returns the result.
func (c CheckoutDir) RevParse(ctx context.Context, args ...string) (string, error) {
	return gitRunner_RevParse(ctx, c, args...)
}

// RevList runs "git rev-list <name>" and returns a slice of commit hashes.
func (c CheckoutDir) RevList(ctx context.Context, args ...string) ([]string, error) {
	return gitRunner_RevList(ctx, c, args...)
}

// ResolveRef returns the commit hash at the HEAD of the given branch.
func (c CheckoutDir) ResolveRef(ctx context.Context, branchName string) (string, error) {
	return gitRunner_ResolveRef(ctx, c, branchName)
}

// Branches runs "git branch" and returns a slice of Branch instances.
func (c CheckoutDir) Branches(ctx context.Context) ([]*Branch, error) {
	return gitRunner_Branches(ctx, c)
}

// GetFile returns the contents of the given file at the given commit.
func (c CheckoutDir) GetFile(ctx context.Context, fileName, commit string) (string, error) {
	return gitRunner_GetFile(ctx, c, fileName, commit)
}

// IsSubmodule returns true if the given path is submodule, ie contains gitlink.
func (c CheckoutDir) IsSubmodule(ctx context.Context, path, commit string) (bool, error) {
	return gitRunner_IsSubmodule(ctx, c, path, commit)
}

// ReadSubmodule returns commit hash of the given path, if the path is git
// submodule. ErrorNotFound is returned if path is not found in the git
// worktree. ErrorNotSubmodule is returned if path exists, but it's not a
// submodule.
func (c CheckoutDir) ReadSubmodule(ctx context.Context, path, commit string) (string, error) {
	return gitRunner_ReadSubmodule(ctx, c, path, commit)
}

// UpdateSubmodule updates git submodule of the given path to the given commit.
// If submodule doesn't exist, it returns ErrorNotFound since it doesn't have
// all necessary information to create a valid submodule (requires an entry in
// .gitmodules).
func (c CheckoutDir) UpdateSubmodule(ctx context.Context, path, commit string) error {
	return gitRunner_UpdateSubmodule(ctx, c, path, commit)
}

// NumCommits returns the number of commits in the repo.
func (c CheckoutDir) NumCommits(ctx context.Context) (int64, error) {
	return gitRunner_NumCommits(ctx, c)
}

// IsAncestor returns true iff A is an ancestor of B.
func (c CheckoutDir) IsAncestor(ctx context.Context, a, b string) (bool, error) {
	return gitRunner_IsAncestor(ctx, c, a, b)
}

// Version returns the Git version.
func (c CheckoutDir) Version(ctx context.Context) (int, int, error) {
	return gitRunner_Version(ctx)
}

// FullHash gives the full commit hash for the given ref.
func (c CheckoutDir) FullHash(ctx context.Context, ref string) (string, error) {
	return gitRunner_FullHash(ctx, c, ref)
}

// CatFile runs "git cat-file -p <ref>:<path>".
func (c CheckoutDir) CatFile(ctx context.Context, ref, path string) ([]byte, error) {
	return gitRunner_CatFile(ctx, c, ref, path)
}

// ReadDir is analogous to os.File.Readdir for a particular ref.
func (c CheckoutDir) ReadDir(ctx context.Context, ref, path string) ([]os.FileInfo, error) {
	return gitRunner_ReadDir(ctx, c, ref, path)
}

// GetRemotes returns a mapping of remote repo name to URL.
func (c CheckoutDir) GetRemotes(ctx context.Context) (map[string]string, error) {
	return gitRunner_GetRemotes(ctx, c)
}

// VFS returns a vfs.FS using Git for the given revision.
func (c CheckoutDir) VFS(ctx context.Context, ref string) (*FS, error) {
	return VFS(ctx, c, ref)
}

// TempCheckout is a temporary Git Checkout.
type TempCheckout struct {
	Checkout
}

// NewTempCheckout returns a TempCheckout instance. Creates a temporary
// directory and then clones the repoUrl into a subdirectory, based on default
// "git clone" behavior.
func NewTempCheckout(ctx context.Context, repoUrl string) (*TempCheckout, error) {
	tmpDir, err := os.MkdirTemp("", "")
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	c, err := NewCheckout(ctx, repoUrl, tmpDir)
	if err != nil {
		return nil, skerr.Wrap(err)
	}
	return &TempCheckout{
		Checkout: c,
	}, nil
}

// Delete removes the TempCheckout's working directory.
func (c *TempCheckout) Delete() {
	deleteDir := filepath.Dir(c.Dir())
	if err := os.RemoveAll(deleteDir); err != nil {
		// Some processes (eg. gclient) leave files that are owned by us but not
		// writeable. Make everything writeable before attempting to delete. We
		// do this only after the first RemoveAll attempt, in case there are a
		// large number of files.
		if _, err2 := exec.RunCwd(context.TODO(), ".", "chmod", "-R", "+w", deleteDir); err2 != nil {
			sklog.Errorf("Failed to remove git.TempCheckout with: %s; and failed to make writeable with: %s", err, err2)
			return
		}
		if err := os.RemoveAll(deleteDir); err != nil {
			sklog.Errorf("Failed to remove git.TempCheckout despite making writeable: %s", err)
		}
	}
}

// Assert that CheckoutDir implements Checkout.
var _ Checkout = CheckoutDir("")
