/**
 * `olam flywheel install-shims` — write backwards-compat shims to ~/.claude/scripts/.
 *
 * Generates a bash shim per spec in SHIM_SPECS and writes it to
 * ~/.claude/scripts/<basename>. Detects existing non-shim files (operator's
 * own scripts or atlas-toolbox-shipped originals) and prompts/backs-up
 * before overwriting. Idempotent — re-runs produce no diff when content
 * matches.
 *
 * Replaces the A1 stub.
 *
 * Plan reference: docs/plans/olam-flywheel-cli-namespace/phase-a-tasks.md § A14
 * Closes part of K1 OQ20 (correct hook-point for shim installation).
 */
import { copyFileSync, existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from 'node:fs';
import { homedir } from 'node:os';
import { dirname, join } from 'node:path';
import { SHIM_SPECS, generateShim } from '../../lib/shim-generator.js';
const SHIM_HEADER_MARKER = '# AUTO-GENERATED by `olam flywheel install-shims`';
/**
 * Programmatic API for refreshing all shims. Used by:
 *   - `olam flywheel install-shims` CLI action (this file).
 *   - `olam skills source pull` post-step (B2 hook point).
 */
export function refreshShims(opts = {}) {
    const targetDir = opts.targetDir ?? join(homedir(), '.claude', 'scripts');
    const results = [];
    let written = 0;
    let overwritten = 0;
    let unchanged = 0;
    let preserved = 0;
    for (const spec of SHIM_SPECS) {
        const result = installOne(spec, targetDir, opts);
        results.push(result);
        switch (result.action) {
            case 'written':
                written += 1;
                break;
            case 'overwritten':
                overwritten += 1;
                break;
            case 'unchanged':
                unchanged += 1;
                break;
            case 'preserved-existing':
                preserved += 1;
                break;
        }
    }
    return { results, written, overwritten, unchanged, preserved };
}
function isOlamGeneratedShim(text) {
    return text.includes(SHIM_HEADER_MARKER);
}
function installOne(spec, targetDir, opts) {
    const targetPath = join(targetDir, spec.basename);
    const newContent = generateShim(spec);
    if (!existsSync(targetPath)) {
        if (opts.dryRun !== true) {
            mkdirSync(dirname(targetPath), { recursive: true });
            writeFileSync(targetPath, newContent, { mode: 0o755 });
        }
        return { basename: spec.basename, action: 'written', targetPath };
    }
    const existing = readFileSync(targetPath, 'utf8');
    if (existing === newContent) {
        return { basename: spec.basename, action: 'unchanged', targetPath };
    }
    // Existing file with different content. If it's our generated shim (older
    // version), overwrite freely. Otherwise it's operator/atlas-toolbox content
    // — back up unless --force.
    if (isOlamGeneratedShim(existing)) {
        if (opts.dryRun !== true) {
            writeFileSync(targetPath, newContent, { mode: 0o755 });
        }
        return { basename: spec.basename, action: 'overwritten', targetPath };
    }
    if (opts.force === true) {
        const backupPath = `${targetPath}.shim-backup-${Math.floor(Date.now() / 1000)}`;
        if (opts.dryRun !== true) {
            copyFileSync(targetPath, backupPath);
            writeFileSync(targetPath, newContent, { mode: 0o755 });
        }
        return { basename: spec.basename, action: 'overwritten', targetPath, backupPath };
    }
    // Without --force, preserve existing.
    return { basename: spec.basename, action: 'preserved-existing', targetPath };
}
export function registerFlywheelInstallShims(parent) {
    parent
        .command('install-shims')
        .description('Install backwards-compat bash shims under ~/.claude/scripts/ that delegate to olam flywheel <subcmd>')
        .option('--force', 'overwrite existing non-shim files (backs them up to .shim-backup-<ts>)')
        .option('--dry-run', 'preview which shims would be written without modifying disk')
        .option('--target-dir <path>', 'override target directory (default: ~/.claude/scripts/); for tests')
        .action((opts) => {
        const targetDir = opts.targetDir ?? join(homedir(), '.claude', 'scripts');
        const summary = refreshShims(opts);
        const lines = [];
        const dryRunSuffix = opts.dryRun === true ? ' (dry-run)' : '';
        for (const result of summary.results) {
            switch (result.action) {
                case 'written':
                    lines.push(`  WRITTEN     ${result.targetPath}${dryRunSuffix}`);
                    break;
                case 'overwritten':
                    lines.push(`  OVERWRITTEN ${result.targetPath}${dryRunSuffix}${result.backupPath !== undefined ? ` (backup: ${result.backupPath})` : ''}`);
                    break;
                case 'unchanged':
                    lines.push(`  UNCHANGED   ${result.targetPath}`);
                    break;
                case 'preserved-existing':
                    lines.push(`  PRESERVED   ${result.targetPath} (existing non-shim file; use --force to overwrite + backup)`);
                    break;
            }
        }
        process.stdout.write(`olam flywheel install-shims → ${targetDir}\n`);
        for (const line of lines)
            process.stdout.write(line + '\n');
        process.stdout.write(`\nwritten: ${summary.written}, overwritten: ${summary.overwritten}, unchanged: ${summary.unchanged}, preserved: ${summary.preserved}\n`);
        // Preserved files indicate operator action needed; exit 1 to surface.
        if (summary.preserved > 0)
            process.exit(1);
    });
}
//# sourceMappingURL=install-shims.js.map