// tools/check-readiness.ts — Completeness checkpoint tool (SPEC-039, SPEC-314, SPEC-716)
import { specStore } from '../storage/index.js';
import { checkSpecReadiness } from '../engine/readiness-checker.js';
import { scoreSpecQuality } from '../engine/spec-quality-scorer.js';
import { buildCheckReadinessSummary } from '../engine/human-summary.js';
import { validateSpecFormat } from '../core/spec-validator.js';
import { resolveProjectId } from './resolve-project-id.js';
// ── Formatting helpers ───────────────────────────────────────────────────────
function formatScore(score) {
    if (score >= 90) {
        return `${score}/100 (Excellent)`;
    }
    if (score >= 70) {
        return `${score}/100 (Ready)`;
    }
    if (score >= 50) {
        return `${score}/100 (Caution)`;
    }
    return `${score}/100 (Not Ready)`;
}
function formatReport(report) {
    const lines = [];
    lines.push(`# Readiness Report — ${report.specId}`);
    lines.push('');
    lines.push(`**Score**: ${formatScore(report.score)}`);
    lines.push(`**Mode**: ${report.mode}`);
    lines.push(`**Ready for implementation**: ${report.ready ? 'YES' : 'NO'}`);
    lines.push('');
    // Score breakdown table
    lines.push('## Score Breakdown');
    lines.push('');
    lines.push('| Category | Points |');
    lines.push('|----------|--------|');
    const breakdown = report.issues.breakdown;
    if (breakdown.hu !== undefined) {
        lines.push(`| HU Completeness | ${breakdown.hu}/20 |`);
    }
    if (breakdown.criteria !== undefined) {
        lines.push(`| Acceptance Criteria | ${breakdown.criteria}/30 |`);
    }
    if (breakdown.files !== undefined) {
        lines.push(`| Files Identified | ${breakdown.files}/20 |`);
    }
    if (breakdown.dependencies !== undefined) {
        lines.push(`| Dependencies | ${breakdown.dependencies}/30 |`);
    }
    lines.push(`| **Total** | **${report.score}/100** |`);
    lines.push('');
    // Blockers
    if (report.issues.blockers.length > 0) {
        lines.push('## Blockers');
        lines.push('');
        for (const blocker of report.issues.blockers) {
            lines.push(`- BLOCKER: ${blocker}`);
        }
        lines.push('');
    }
    // Warnings
    if (report.issues.warnings.length > 0) {
        lines.push('## Warnings');
        lines.push('');
        for (const warning of report.issues.warnings) {
            lines.push(`- WARNING: ${warning}`);
        }
        lines.push('');
    }
    // Recommendations
    if (report.recommendations.length > 0) {
        lines.push('## Recommendations');
        lines.push('');
        for (const rec of report.recommendations) {
            lines.push(`- ${rec}`);
        }
        lines.push('');
    }
    // SPEC-042: Config health hint
    lines.push('## Config Health');
    lines.push('');
    lines.push('- Run `check_config_health` to detect silent misconfigurations (tsconfig coverage, CI script references, build artifact gaps) that block DoR.');
    lines.push('');
    return lines.join('\n');
}
// ── Handler ──────────────────────────────────────────────────────────────────
export async function handleCheckReadiness(args) {
    const projectId = resolveProjectId(args);
    if (!projectId) {
        return {
            content: [{ type: 'text', text: 'Provide projectId or projectPath.' }],
            isError: true,
        };
    }
    const { specId, mode = 'strict' } = args;
    const spec = await specStore.getSpec(projectId, specId);
    if (!spec) {
        return {
            content: [
                {
                    type: 'text',
                    text: `Spec '${specId}' not found in project '${projectId}'`,
                },
            ],
            isError: true,
        };
    }
    // SPEC-716: Ground yes/no decision in validateSpecFormat.
    // The existing checkSpecReadiness call and formatReport are preserved for
    // the rich human-readable output. validateSpecFormat drives the yes/no gate
    // and its errors/warnings are surfaced in structuredContent.validationResult.
    const [report, qualityReport, validationResult] = await Promise.all([
        checkSpecReadiness(spec, mode),
        scoreSpecQuality(spec),
        validateSpecFormat(spec, { readinessMode: mode, skipQuality: true }),
    ]);
    // SPEC-716: Ground ready flag in unified ValidationResult.
    // Only non-file-access errors from validateSpecFormat are surfaced in the
    // report — MISSING_FRONTMATTER due to file-not-found is best-effort since
    // the readiness checker already handles missing files gracefully.
    const vr = validationResult;
    const hardFormatErrors = vr.errors.filter((e) => e.code !== 'MISSING_FRONTMATTER' && !(e.code === 'READINESS_CHECK_FAILED'));
    const hardFormatMessages = hardFormatErrors.map((e) => e.message);
    const formatWarnings = vr.warnings
        .filter((w) => w.code !== 'READINESS_CHECK_FAILED')
        .map((w) => w.message);
    // Merge hard format errors into report blockers (avoid duplicates)
    for (const msg of hardFormatMessages) {
        if (!report.issues.blockers.includes(msg)) {
            report.issues.blockers.push(msg);
        }
    }
    for (const msg of formatWarnings) {
        if (!report.issues.warnings.includes(msg)) {
            report.issues.warnings.push(msg);
        }
    }
    // Ground ready: only false if BOTH readiness report and format gate agree
    // (or format has hard non-file errors)
    report.ready = report.ready && hardFormatErrors.length === 0;
    // SPEC-612: recommend adding outOfScope items when none are declared
    if (spec.outOfScope === undefined || spec.outOfScope.length === 0) {
        report.recommendations.push('Add outOfScope items to the spec frontmatter to declare explicit scope boundaries (SPEC-612). This reduces scope creep during implementation.');
    }
    const qualityScore = qualityReport.score;
    const formatted = formatReport(report);
    const humanSummary = buildCheckReadinessSummary(report.score, report.issues.blockers.length);
    return {
        content: [
            { type: 'text', text: formatted },
            { type: 'text', text: humanSummary },
        ],
        structuredContent: {
            specId: report.specId,
            score: report.score,
            ready: report.ready,
            mode: report.mode,
            issues: report.issues,
            recommendations: report.recommendations,
            qualityScore,
            humanSummary,
            validationResult: vr,
        },
    };
}
//# sourceMappingURL=check-readiness.js.map