"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.runChecks = runChecks;
const Listr = require('listr');
const ANSI = {
    reset: '\x1b[0m',
    dim: '\x1b[2m',
    red: '\x1b[31m',
    green: '\x1b[32m',
    yellow: '\x1b[33m',
    cyan: '\x1b[36m',
};
const c = (color, s) => process.stdout.isTTY ? `${ANSI[color]}${s}${ANSI.reset}` : s;
const INLINE_DETAIL_MAX = 40;
function wrap(text, width) {
    if (width <= 0)
        return [text];
    const out = [];
    for (const para of text.split('\n')) {
        const words = para.split(/\s+/).filter(Boolean);
        let cur = '';
        for (const w of words) {
            if (cur.length === 0) {
                cur = w;
            }
            else if (cur.length + 1 + w.length <= width) {
                cur += ' ' + w;
            }
            else {
                out.push(cur);
                cur = w;
            }
        }
        out.push(cur);
    }
    return out;
}
/**
 * Run a list of doctor checks with a Listr spinner UI and return a summary.
 * Listr's default renderer clips lines to terminal width, so we keep titles
 * compact and print full diagnostic text in a "Details" section below the run.
 */
async function runChecks(header, checks) {
    const outcomes = [];
    console.log('');
    console.log(c('cyan', header));
    console.log(c('dim', '─'.repeat(header.length)));
    const tasks = new Listr(checks.map(check => ({
        title: check.title,
        skip: () => {
            const r = check.skip?.();
            if (r) {
                outcomes.push({
                    title: check.title,
                    status: 'skip',
                    detail: typeof r === 'string' ? r : undefined,
                });
            }
            return r;
        },
        task: async (_ctx, task) => {
            const result = await check.run();
            if (result.ok) {
                outcomes.push({ title: check.title, status: 'pass', detail: result.detail });
                if (result.detail && result.detail.length <= INLINE_DETAIL_MAX) {
                    task.title = `${check.title} ${c('dim', `(${result.detail})`)}`;
                }
                return;
            }
            if (check.severity === 'optional') {
                outcomes.push({ title: check.title, status: 'warn', detail: result.detail });
                task.title = `${check.title} ${c('yellow', '(warning — see details)')}`;
                return;
            }
            outcomes.push({ title: check.title, status: 'fail', detail: result.detail });
            throw new Error('see details below');
        },
    })), { exitOnError: false, concurrent: false });
    try {
        await tasks.run();
    }
    catch {
        // listr re-throws aggregated errors when exitOnError is false; outcomes captured separately
    }
    const counts = {
        pass: outcomes.filter(o => o.status === 'pass').length,
        fail: outcomes.filter(o => o.status === 'fail').length,
        warn: outcomes.filter(o => o.status === 'warn').length,
        skip: outcomes.filter(o => o.status === 'skip').length,
    };
    const issues = outcomes.filter(o => o.status === 'fail' || o.status === 'warn');
    if (issues.length > 0) {
        const width = Math.max(40, (process.stdout.columns || 80) - 6);
        console.log('');
        console.log(c('cyan', 'Details:'));
        for (const o of issues) {
            const isFail = o.status === 'fail';
            const color = isFail ? 'red' : 'yellow';
            const marker = isFail ? '✖' : '⚠';
            console.log(`  ${c(color, marker)} ${o.title}`);
            const lines = wrap(o.detail || 'no additional info', width);
            for (const line of lines)
                console.log(`      ${line}`);
        }
    }
    const summary = {
        total: checks.length,
        passed: counts.pass,
        failed: counts.fail,
        warnings: counts.warn,
        skipped: counts.skip,
        exitCode: counts.fail > 0 ? 1 : 0,
    };
    console.log('');
    if (summary.failed > 0) {
        console.log(c('red', `✖ ${summary.failed} required check${summary.failed === 1 ? '' : 's'} failed.`));
    }
    else if (summary.warnings > 0) {
        console.log(c('yellow', `⚠ All required checks passed (${summary.warnings} optional warning${summary.warnings === 1 ? '' : 's'}).`));
    }
    else {
        console.log(c('green', '✔ All checks passed.'));
    }
    console.log(c('dim', `  total=${summary.total} passed=${summary.passed} failed=${summary.failed} warnings=${summary.warnings} skipped=${summary.skipped}`));
    console.log('');
    return summary;
}
//# sourceMappingURL=runner.js.map