// @crash-shield-ignore-file — config/cache reader for Planu-controlled JSON; writer is this codebase, shape guaranteed by build/seed.
// tools/init-project/git-setup.ts — Git configuration during init_project
import { handleSetupHooks } from '../git/hook-ops.js';
import { detectGitFlowType, git } from '../git/git-helpers.js';
import { access, readFile, writeFile } from 'node:fs/promises';
import { join, dirname } from 'node:path';
/**
 * SPEC-539: Walk up the directory tree to detect if a git repository exists
 * at or above the given path. Returns the root of the git repo, or null.
 */
async function findGitRoot(startPath) {
    let current = startPath;
    // Traverse up until we find .git or reach filesystem root
    for (let i = 0; i < 20; i++) {
        try {
            await access(join(current, '.git'));
            return current;
        }
        catch {
            const parent = dirname(current);
            if (parent === current) {
                break;
            } // reached filesystem root
            current = parent;
        }
    }
    return null;
}
/** SPEC-001 + SPEC-539: Setup git hooks, detect branching model, and configure .gitignore.
 * SPEC-539: Only installs hooks if a git repository is detected — never creates .git. */
export async function runGitSetup(projectPath, projectId) {
    // SPEC-539: Detect git repo before doing any git operations
    const gitRoot = await findGitRoot(projectPath);
    const gitRepoDetected = gitRoot !== null;
    // Auto-install git hooks (best-effort, only if git repo exists)
    let hooksInstalled = [];
    if (gitRepoDetected) {
        try {
            const hookResult = await handleSetupHooks(projectId);
            if (!hookResult.isError) {
                const hookData = JSON.parse(hookResult.content[0]?.text ?? '{}');
                hooksInstalled = hookData.hooksInstalled ?? [];
            }
        }
        catch {
            // Hooks setup is best-effort — don't fail init_project
        }
    }
    // Auto-detect branching model (best-effort, only if git repo exists)
    let gitFlowType = 'unknown';
    if (gitRepoDetected) {
        try {
            gitFlowType = await detectGitFlowType(projectPath);
        }
        catch {
            // Not a git repo — skip
        }
    }
    // Auto-configure .gitignore (best-effort)
    const gitignoreUpdated = await configureGitignore(projectPath);
    // SPEC-646: Remove planu/*.html from git tracking — they are regenerable, not source files
    if (gitRepoDetected) {
        await untrackHtmlFiles(projectPath);
    }
    return { hooksInstalled, gitFlowType, gitignoreUpdated, gitRepoDetected };
}
/** SPEC-646: Delete legacy planu/*.html files from disk and remove from git index.
 *  These files are regenerable — committing them wastes ≥1MB per repo clone. */
async function untrackHtmlFiles(projectPath) {
    const htmlFiles = ['planu/index.html', 'planu/roadmap.html'];
    // Remove from git index if tracked (best-effort)
    try {
        const { stdout } = await git(projectPath, ['ls-files', ...htmlFiles]);
        const tracked = stdout.trim().split('\n').filter(Boolean);
        if (tracked.length > 0) {
            await git(projectPath, ['rm', '--force', ...tracked]);
        }
    }
    catch {
        /* not a git repo or files not tracked */
    }
    // Also delete any remaining files from disk (e.g. not tracked but still present)
    for (const rel of htmlFiles) {
        try {
            const { unlink } = await import('node:fs/promises');
            await unlink(join(projectPath, rel));
        }
        catch {
            /* file doesn't exist or can't be deleted — skip */
        }
    }
}
/** SPEC-466: Also exported for list_specs auto-cleanup. */
export async function configureGitignoreForPlanu(projectPath) {
    return configureGitignore(projectPath);
}
async function configureGitignore(projectPath) {
    const gitignorePath = join(projectPath, '.gitignore');
    try {
        let gitignoreContent = '';
        try {
            gitignoreContent = await readFile(gitignorePath, 'utf-8');
        }
        catch {
            /* file doesn't exist */
        }
        // Remove planu/ from .gitignore if present — specs MUST be tracked in git
        const protectedPaths = ['planu/', 'planu.json', 'planu/*'];
        const lines = gitignoreContent.split('\n');
        const cleaned = lines.filter((line) => !protectedPaths.some((p) => line.trim() === p));
        let updated = cleaned.length !== lines.length;
        if (updated) {
            gitignoreContent = cleaned.join('\n');
        }
        // Add data/ if missing — runtime data should NOT be tracked
        const linesToAdd = [];
        if (!gitignoreContent.includes('data/')) {
            linesToAdd.push('data/');
        }
        // SPEC-466: Gitignore regenerable planu/ files to prevent merge conflicts
        // SPEC-724: Gitignore heal_spec_docs backup files (.bak.<ts>)
        const planuIgnores = [
            'planu/*.html',
            'planu/status.json',
            'planu/CHANGELOG.md',
            'planu/.housekeeping-history.jsonl',
            'planu/audits/',
            'planu/handoffs/',
            'planu/data/',
            'planu/state/',
            'planu/.locks/',
            'planu/specs/data/',
            'planu/specs/**/.analysis.json',
            'planu/specs/**/technical-report.html',
            'planu/specs/**/reference/',
            'planu/specs/**/*.bak.*',
        ];
        for (const entry of planuIgnores) {
            if (!gitignoreContent.includes(entry)) {
                linesToAdd.push(entry);
            }
        }
        if (linesToAdd.length > 0 || updated) {
            const separator = gitignoreContent.endsWith('\n') || gitignoreContent === '' ? '' : '\n';
            const addition = linesToAdd.length > 0
                ? `${separator}# Planu (auto-configured)\n${linesToAdd.join('\n')}\n`
                : '';
            await writeFile(gitignorePath, gitignoreContent + addition, 'utf-8');
            updated = true;
        }
        return updated;
    }
    catch {
        /* best-effort */
        return false;
    }
}
//# sourceMappingURL=git-setup.js.map