package git

import (
	"fmt"
	"io"
	"os/exec"
	"strings"
)

// IsClean checks if the repo in the current directory is clean.
//
// Untracked files are okay, but modified, added, or deleted files are not.
func IsClean() (bool, error) {
	cmd := exec.Command("git", "status", "--porcelain")
	out, err := cmd.Output()
	if err != nil {
		return false, fmt.Errorf("git status failed: %v", err)
	}

	lines := strings.Split(string(out), "\n")
	for _, line := range lines {
		if line == "" {
			continue
		}

		// Ignore untracked files.
		if !strings.HasPrefix(line, "??") {
			return false, nil
		}
	}

	return true, nil
}

// ApplyPatches applies a list of patches to the current repo with `git am <paths>`.
//
// The combined output of the command is written to the given writer.
func ApplyPatches(paths []string, writer io.Writer) error {
	cmd := exec.Command("git", append([]string{"am"}, paths...)...)
	cmd.Stdout = writer
	cmd.Stderr = writer
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("`git am` command failed: %v", err)
	}
	return nil
}

// Add adds a list of files to the current repo with `git add <files>`.
//
// The combined output of the command is written to the given writer.
func Add(files []string, writer io.Writer) error {
	cmd := exec.Command("git", append([]string{"add"}, files...)...)
	cmd.Stdout = writer
	cmd.Stderr = writer
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("`git add` command failed: %v", err)
	}
	return nil
}

// Commit commits changes to the current repo with `git commit <message>`.
//
// The combined output of the command is written to the given writer.
func Commit(message string, writer io.Writer) error {
	cmd := exec.Command("git", "commit", "-m", message)
	cmd.Stdout = writer
	cmd.Stderr = writer
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("`git commit` command failed: %v", err)
	}
	return nil
}

// SwitchToNewBranch creates a branch in the current repo and switches to
// it using `git switch -c <branch>`.
//
// The combined output of the command is written to the given writer.
func SwitchToNewBranch(branch string, writer io.Writer) error {
	cmd := exec.Command("git", "switch", "-c", branch)
	cmd.Stdout = writer
	cmd.Stderr = writer
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("command %s failed: %v", cmd, err)
	}
	return nil
}

// FindCommitByPattern searches the git log for the provided pattern and
// returns the first commit hash it finds.
func FindCommitByPattern(pattern string) (string, error) {
	cmd := exec.Command("git", "log", "-n1", "--format=%H", "--grep", pattern)
	out, err := cmd.CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("command %s failed: %v", cmd, err)
	}

	return strings.TrimSpace(string(out)), nil
}

// FormatPatch formats a revision range as patches and writes them to the
// provided output directory.
//
// The combined output of the command is written to the given writer.
func FormatPatch(revisionRange, outDir string, writer io.Writer) error {
	cmd := exec.Command("git", "format-patch", revisionRange, "-o", outDir)
	cmd.Stdout = writer
	cmd.Stderr = writer
	if err := cmd.Run(); err != nil {
		return fmt.Errorf("command %s failed: %v", cmd, err)
	}
	return nil
}
