import * as path from "node:path";
import * as fsSync from "node:fs";
import { execSync } from "node:child_process";
/**
 * Check if a directory is a git repository
 * @param dirPath Directory path
 * @returns "Yes" if it's a git repository, "No" otherwise
 */
export function isGitRepository(dirPath) {
    try {
        // Check if .git directory exists in current directory or any parent directory
        let currentPath = path.resolve(dirPath);
        while (currentPath !== path.dirname(currentPath)) {
            const gitPath = path.join(currentPath, ".git");
            if (fsSync.existsSync(gitPath)) {
                return "Yes";
            }
            currentPath = path.dirname(currentPath);
        }
        return "No";
    }
    catch {
        return "No";
    }
}
/**
 * Get the root directory of the git repository
 * @param cwd Working directory
 * @returns Repository root path
 */
export function getGitRepoRoot(cwd) {
    try {
        return execSync("git rev-parse --show-toplevel", {
            cwd,
            encoding: "utf8",
            stdio: ["ignore", "pipe", "ignore"],
        }).trim();
    }
    catch {
        return cwd;
    }
}
/**
 * Get the common directory of the git repository (handles worktrees)
 * @param cwd Working directory
 * @returns Repository common directory path
 */
export function getGitCommonDir(cwd) {
    try {
        const commonDir = execSync("git rev-parse --git-common-dir", {
            cwd,
            encoding: "utf8",
            stdio: ["ignore", "pipe", "ignore"],
        }).trim();
        return path.resolve(cwd, commonDir);
    }
    catch {
        return getGitRepoRoot(cwd);
    }
}
/**
 * Get the main repository root directory (the first worktree in the list)
 * @param cwd Working directory
 * @returns Main repository root path
 */
export function getGitMainRepoRoot(cwd) {
    try {
        const output = execSync("git worktree list --porcelain", {
            cwd,
            encoding: "utf8",
            stdio: ["ignore", "pipe", "ignore"],
        }).trim();
        const lines = output.split("\n");
        if (lines.length > 0 && lines[0].startsWith("worktree ")) {
            return lines[0].substring("worktree ".length).trim();
        }
        return getGitRepoRoot(cwd);
    }
    catch {
        return getGitRepoRoot(cwd);
    }
}
/**
 * Get the default remote branch (e.g., origin/main)
 * @param cwd Working directory
 * @returns Default remote branch name
 */
export function getDefaultRemoteBranch(cwd) {
    // 1. Try git symbolic-ref refs/remotes/origin/HEAD
    try {
        const head = execSync("git symbolic-ref refs/remotes/origin/HEAD", {
            cwd,
            encoding: "utf8",
            stdio: ["ignore", "pipe", "ignore"],
        }).trim();
        return head.replace("refs/remotes/", "");
    }
    catch {
        // Ignore error and proceed to next step
    }
    // 2. Check if origin/main exists
    try {
        execSync("git rev-parse --verify origin/main", {
            cwd,
            stdio: "ignore",
        });
        return "origin/main";
    }
    catch {
        // Ignore error and proceed to next step
    }
    // 3. Check if origin/master exists
    try {
        execSync("git rev-parse --verify origin/master", {
            cwd,
            stdio: "ignore",
        });
        return "origin/master";
    }
    catch {
        // Ignore error and proceed to next step
    }
    // 4. Try to get the current branch's upstream
    try {
        return execSync("git rev-parse --abbrev-ref --symbolic-full-name @{u}", {
            cwd,
            encoding: "utf8",
            stdio: ["ignore", "pipe", "ignore"],
        }).trim();
    }
    catch {
        // Ignore error and proceed to next step
    }
    // 5. Try to get the current branch name
    try {
        return execSync("git rev-parse --abbrev-ref HEAD", {
            cwd,
            encoding: "utf8",
            stdio: ["ignore", "pipe", "ignore"],
        }).trim();
    }
    catch {
        // Ignore error and proceed to next step
    }
    // 6. Fallback to origin/main
    return "origin/main";
}
/**
 * Check if there are uncommitted changes in the working directory
 * @param cwd Working directory
 * @returns True if there are uncommitted changes
 */
export function hasUncommittedChanges(cwd) {
    try {
        const status = execSync("git status --porcelain", {
            cwd,
            encoding: "utf8",
            stdio: ["ignore", "pipe", "ignore"],
        }).trim();
        return status.length > 0;
    }
    catch {
        return false;
    }
}
/**
 * Check if there are new commits in the current branch that are not in the base branch
 * @param cwd Working directory
 * @param baseBranch Base branch name (e.g., origin/main)
 * @returns True if there are new commits
 */
export function hasNewCommits(cwd, baseBranch) {
    try {
        const range = baseBranch ? `${baseBranch}..HEAD` : "@{u}..HEAD";
        const log = execSync(`git log ${range} --oneline`, {
            cwd,
            encoding: "utf8",
            stdio: ["ignore", "pipe", "ignore"],
        }).trim();
        return log.length > 0;
    }
    catch {
        return false;
    }
}
