"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.registerDoctorCommand = registerDoctorCommand;
const daemon_discovery_js_1 = require("../../lib/daemon-discovery.js");
const runtime_env_js_1 = require("../runtime-env.js");
const ui_js_1 = require("../ui.js");
/**
 * Below this age, we treat a restart as "recent" — the user is most
 * likely to hit the port-forward staleness window in this slice and
 * we should surface the known-issue hint loudly.
 *
 * Five minutes covers: the editor's proxy reconnect window after a
 * restart, the typical "I ran chorus update and now the page is blank"
 * debug timeline, and isn't so long that a healthy daemon noise-floor
 * triggers the warning.
 */
const RECENT_RESTART_WINDOW_MS = 5 * 60 * 1000;
async function gatherReport() {
    const { detectAllClis } = await import('../../lib/cli-detect.js');
    const { loadCapturedPath } = await import('../../lib/runtime-path.js');
    const { cliPaths } = await import('../../lib/cli-paths.js');
    await cliPaths.refreshCache();
    const detection = detectAllClis(true);
    const capturedPath = await loadCapturedPath();
    const manualPaths = await cliPaths.listAll();
    const compactManual = {};
    for (const [id, p] of Object.entries(manualPaths)) {
        if (p)
            compactManual[id] = p;
    }
    const info = (0, daemon_discovery_js_1.readDaemonInfo)();
    let daemonAgeMs = null;
    if (info?.startedAt) {
        const started = Date.parse(info.startedAt);
        if (Number.isFinite(started)) {
            daemonAgeMs = Math.max(0, Date.now() - started);
        }
    }
    return {
        detection,
        capturedPath,
        daemonPath: process.env.PATH ?? '',
        manualPaths: compactManual,
        runtimeEnv: (0, runtime_env_js_1.detectRuntimeEnv)(),
        daemonAgeMs,
    };
}
function printReport(r) {
    const labelMap = {
        'claude-code': 'claude',
        'codex-cli': 'codex',
        'gemini-cli': 'gemini',
        'opencode-cli': 'opencode',
        'kimi-cli': 'kimi',
        'grok-cli': 'grok',
        'antigravity-cli': 'agy',
    };
    console.log('');
    console.log((0, ui_js_1.header)(ui_js_1.sym.pointer, 'Chorus doctor'));
    console.log('');
    console.log(ui_js_1.c.bold('  CLI detection'));
    console.log('');
    for (const d of r.detection) {
        const name = labelMap[d.id] ?? d.id;
        if (d.found) {
            const sourceTag = d.source === 'manual'
                ? ui_js_1.c.cyan('manual')
                : d.source === 'fallback'
                    ? ui_js_1.c.yellow('fallback')
                    : ui_js_1.c.dim('PATH');
            console.log(`    ${ui_js_1.sym.ok} ${ui_js_1.c.bold(name.padEnd(10))} ${ui_js_1.c.dim(d.path ?? '')} ${ui_js_1.c.dim('(')}${sourceTag}${ui_js_1.c.dim(')')}`);
        }
        else {
            const reason = d.reason ? ui_js_1.c.dim(` — ${d.reason}`) : '';
            console.log(`    ${ui_js_1.sym.err} ${ui_js_1.c.bold(name.padEnd(10))} ${ui_js_1.c.red('not found')}${reason}`);
        }
    }
    console.log('');
    console.log(ui_js_1.c.bold('  PATH visibility'));
    console.log('');
    console.log(`    daemon PATH:      ${ui_js_1.c.dim(`${r.daemonPath.split(':').length} dirs`)} ${r.daemonPath ? ui_js_1.c.dim(`(${r.daemonPath.slice(0, 80)}${r.daemonPath.length > 80 ? '…' : ''})`) : ''}`);
    if (r.capturedPath) {
        console.log(`    captured shell:   ${ui_js_1.c.dim(`${r.capturedPath.split(':').length} dirs`)} ${ui_js_1.c.dim(`(${r.capturedPath.slice(0, 80)}${r.capturedPath.length > 80 ? '…' : ''})`)}`);
        const inDaemon = new Set(r.daemonPath.split(':'));
        const missing = r.capturedPath
            .split(':')
            .filter((p) => p && !inDaemon.has(p));
        if (missing.length > 0) {
            console.log('');
            console.log(`    ${ui_js_1.c.yellow('!')} ${missing.length} dirs in your shell PATH but NOT in the daemon's PATH:`);
            for (const p of missing.slice(0, 8)) {
                console.log(`      ${ui_js_1.c.dim(p)}`);
            }
            if (missing.length > 8) {
                console.log(`      ${ui_js_1.c.dim(`… +${missing.length - 8} more`)}`);
            }
            console.log('');
            console.log(`    ${ui_js_1.c.dim('Tip:')} restart the daemon with ${ui_js_1.c.bold('chorus stop && chorus start')} to re-capture.`);
        }
    }
    else {
        console.log(`    captured shell:   ${ui_js_1.c.dim('not captured yet — run ')}${ui_js_1.c.bold('chorus init')}${ui_js_1.c.dim(' or ')}${ui_js_1.c.bold('chorus start')}`);
    }
    if ((0, runtime_env_js_1.isRemoteDevEnv)(r.runtimeEnv)) {
        printRemoteSessionSection(r);
    }
    if (Object.keys(r.manualPaths).length > 0) {
        console.log('');
        console.log(ui_js_1.c.bold('  Manual overrides'));
        console.log('');
        for (const [id, p] of Object.entries(r.manualPaths)) {
            const name = labelMap[id] ?? id;
            console.log(`    ${ui_js_1.sym.ok} ${ui_js_1.c.bold(name.padEnd(10))} ${ui_js_1.c.dim(p)}`);
        }
    }
    // Final hint when something looks off
    const missingCli = r.detection.filter((d) => !d.found);
    if (missingCli.length > 0) {
        console.log('');
        console.log(ui_js_1.c.bold('  Next steps'));
        console.log('');
        console.log(`    ${ui_js_1.c.dim('•')} Visit ${ui_js_1.c.cyan('http://127.0.0.1:5050/onboarding')} → "I know where it is"`);
        console.log(`      to paste a path for any missing CLI.`);
        console.log(`    ${ui_js_1.c.dim('•')} Or run ${ui_js_1.c.bold('chorus stop && chorus start')} from your usual terminal so`);
        console.log(`      we re-capture the PATH that has the CLI.`);
    }
    console.log('');
}
function formatDaemonAge(ms) {
    const totalSec = Math.round(ms / 1000);
    if (totalSec < 60)
        return `${totalSec}s ago`;
    const totalMin = Math.round(totalSec / 60);
    if (totalMin < 60)
        return `${totalMin}m ago`;
    const totalHr = Math.round(totalMin / 60);
    if (totalHr < 24)
        return `${totalHr}h ago`;
    return `${Math.round(totalHr / 24)}d ago`;
}
function printRemoteSessionSection(r) {
    const editor = r.runtimeEnv.kind === 'cursor-remote'
        ? 'Cursor Remote-SSH'
        : r.runtimeEnv.kind === 'codespaces'
            ? 'GitHub Codespaces'
            : 'VSCode Remote-SSH';
    console.log('');
    console.log(ui_js_1.c.bold('  Remote session'));
    console.log('');
    console.log(`    ${ui_js_1.sym.info} ${editor} detected.`);
    if (r.daemonAgeMs === null) {
        console.log(`      ${ui_js_1.c.dim('No running daemon — start one with ')}${ui_js_1.c.bold('chorus start')}${ui_js_1.c.dim('.')}`);
        return;
    }
    const recent = r.daemonAgeMs < RECENT_RESTART_WINDOW_MS;
    console.log(`      Daemon started ${ui_js_1.c.dim(formatDaemonAge(r.daemonAgeMs))}.`);
    if (recent) {
        console.log('');
        console.log(`    ${ui_js_1.c.yellow('!')} Known-issue check: a recent restart can leave your editor's port-forward`);
        console.log(`      bound to the old daemon's PID, so ${ui_js_1.c.cyan('http://127.0.0.1:5050')} loads blank.`);
        console.log(`      Open the ${ui_js_1.c.bold('Ports')} panel and re-forward ${ui_js_1.c.bold('5050')} to rebind.`);
    }
}
function registerDoctorCommand(program) {
    program
        .command('doctor')
        .description('Diagnose CLI detection + PATH issues — what the daemon sees vs what your shell sees')
        .action(async () => {
        try {
            const report = await gatherReport();
            printReport(report);
        }
        catch (err) {
            console.error('doctor failed:', err instanceof Error ? err.message : err);
            process.exit(1);
        }
    });
}
//# sourceMappingURL=doctor.js.map