import { hashProjectPath } from '../storage/base-store.js';
import { getSpec } from '../storage/spec-store.js';
import { getComplianceConfig } from '../storage/compliance-store.js';
import { detectComplianceContext, checkCompliance } from '../engine/compliance-checker.js';
import { scoreCompliance } from '../engine/verifier/compliance-scorer.js';
import { saveComplianceScore, getAllComplianceScores } from '../storage/compliance-score-store.js';
import { analyzeComplianceGaps } from '../engine/compliance-reporter.js';
// ---------------------------------------------------------------------------
// Mode: score — compliance_score_report logic
// ---------------------------------------------------------------------------
function formatScore(score) {
    const levelEmoji = score.level === 'compliant' ? '(ok)' : score.level === 'partial' ? '(!)' : '(x)';
    const lines = [
        `## Compliance Report — ${score.specId}`,
        '',
        `**Score**: ${score.score}/100 ${levelEmoji} (${score.level})`,
        `**Checked at**: ${score.checkedAt}`,
        '',
        `| Criteria | Count |`,
        `|----------|-------|`,
        `| Total    | ${score.totalCriteria} |`,
        `| Verified | ${score.verifiedCriteria} |`,
        `| Partial  | ${score.partialCriteria} |`,
        `| Unverified | ${score.unverifiedCriteria} |`,
    ];
    if (score.criteriaDetails.length > 0) {
        lines.push('', '### Criteria Details', '');
        for (const detail of score.criteriaDetails) {
            const icon = detail.status === 'verified' ? '[ok]' : detail.status === 'partial' ? '[!]' : '[x]';
            lines.push(`${icon} **${detail.status.toUpperCase()}**: ${detail.criterion}`);
            if (detail.evidence.length > 0) {
                lines.push(`   Evidence: ${detail.evidence.slice(0, 3).join(', ')}`);
            }
        }
    }
    return lines.join('\n');
}
function formatReport(report) {
    const lines = [
        `## Compliance Score Report`,
        '',
        `**Project**: ${report.projectPath}`,
        `**Generated**: ${report.generatedAt}`,
        `**Overall Average**: ${report.overallAverage.toFixed(1)}/100`,
        '',
        `| Status | Count |`,
        `|--------|-------|`,
        `| Total Specs | ${report.totalSpecs} |`,
        `| Compliant (>=80) | ${report.compliantCount} |`,
        `| Partial (60-79) | ${report.partialCount} |`,
        `| Non-compliant (<60) | ${report.nonCompliantCount} |`,
    ];
    if (report.scores.length > 0) {
        lines.push('', '### Per-Spec Scores', '');
        lines.push('| Spec ID | Score | Level |');
        lines.push('|---------|-------|-------|');
        for (const s of report.scores) {
            lines.push(`| ${s.specId} | ${s.score} | ${s.level} |`);
        }
    }
    return lines.join('\n');
}
async function handleScoreMode(input) {
    const projectPath = input.projectPath ?? '';
    if (!projectPath) {
        return {
            content: [{ type: 'text', text: 'projectPath is required for mode=score.' }],
            isError: true,
        };
    }
    const projectId = input.projectId ?? hashProjectPath(projectPath);
    const allScores = await getAllComplianceScores(projectId);
    let scores = Object.values(allScores);
    if (input.minScore !== undefined) {
        const threshold = input.minScore;
        scores = scores.filter((s) => s.score < threshold);
    }
    scores.sort((a, b) => a.score - b.score);
    const totalSpecs = scores.length;
    const compliantCount = scores.filter((s) => s.level === 'compliant').length;
    const partialCount = scores.filter((s) => s.level === 'partial').length;
    const nonCompliantCount = scores.filter((s) => s.level === 'non-compliant').length;
    const overallAverage = totalSpecs > 0 ? scores.reduce((sum, s) => sum + s.score, 0) / totalSpecs : 0;
    const report = {
        projectPath,
        overallAverage: Math.round(overallAverage * 10) / 10,
        totalSpecs,
        compliantCount,
        partialCount,
        nonCompliantCount,
        scores,
        generatedAt: new Date().toISOString(),
    };
    return { content: [{ type: 'text', text: formatReport(report) }] };
}
// ---------------------------------------------------------------------------
// Mode: gaps — compliance_gap_analysis logic
// ---------------------------------------------------------------------------
function handleGapsMode(input) {
    const standard = input.standard ?? 'soc2-type2';
    const gaps = analyzeComplianceGaps(standard);
    if (gaps.length === 0) {
        return {
            content: [
                {
                    type: 'text',
                    text: `No compliance gaps found for ${standard}. All controls satisfied.`,
                },
            ],
        };
    }
    const gapLines = gaps.map((g) => `- [${g.severity.toUpperCase()}] ${g.controlId} — ${g.controlName}\n` +
        `  Gap: ${g.gap}\n` +
        `  Recommendation: ${g.recommendation}`);
    return {
        content: [
            {
                type: 'text',
                text: [
                    `Compliance gap analysis for ${standard} (${gaps.length} gaps):`,
                    '',
                    ...gapLines,
                ].join('\n'),
            },
        ],
    };
}
// ---------------------------------------------------------------------------
// Mode: verify — verify_spec_compliance logic
// ---------------------------------------------------------------------------
async function handleVerifyMode(input) {
    const { specId, projectPath } = input;
    if (!specId || !projectPath) {
        return {
            content: [{ type: 'text', text: 'specId and projectPath are required for mode=verify.' }],
            isError: true,
        };
    }
    const score = await scoreCompliance(specId, projectPath);
    const projectId = input.projectId ?? hashProjectPath(projectPath);
    await saveComplianceScore(projectId, score);
    return { content: [{ type: 'text', text: formatScore(score) }] };
}
// ---------------------------------------------------------------------------
// Mode: full — score + gaps + verify combined
// ---------------------------------------------------------------------------
async function handleFullMode(input) {
    const sections = [];
    // Score section
    const scoreResult = await handleScoreMode(input);
    const scoreText = scoreResult.content[0];
    if (scoreText?.type === 'text') {
        sections.push('# Score\n', scoreText.text);
    }
    // Gaps section
    const gapsResult = handleGapsMode(input);
    const gapsText = gapsResult.content[0];
    if (gapsText?.type === 'text') {
        sections.push('\n# Gaps\n', gapsText.text);
    }
    // Verify section (only if specId provided)
    if (input.specId && input.projectPath) {
        const verifyResult = await handleVerifyMode(input);
        const verifyText = verifyResult.content[0];
        if (verifyText?.type === 'text') {
            sections.push('\n# Verify\n', verifyText.text);
        }
    }
    return { content: [{ type: 'text', text: sections.join('\n') }] };
}
// ---------------------------------------------------------------------------
// Legacy check_compliance mode (frameworks-based AC gap detection)
// ---------------------------------------------------------------------------
async function handleLegacyCheckMode(input) {
    const projectId = hashProjectPath(input.projectPath);
    const spec = await getSpec(projectId, input.specId);
    if (spec === null) {
        return {
            content: [
                {
                    type: 'text',
                    text: `Spec ${input.specId} not found. Check the ID and try again.`,
                },
            ],
            isError: true,
        };
    }
    let frameworks = input.frameworks ?? [];
    if (frameworks.length === 0) {
        const detected = detectComplianceContext(spec.title, '');
        if (detected.length > 0) {
            frameworks = detected;
        }
        else {
            const config = await getComplianceConfig(input.projectPath);
            frameworks = config?.frameworks ?? [];
        }
    }
    if (frameworks.length === 0) {
        return {
            content: [
                {
                    type: 'text',
                    text: 'No compliance frameworks detected or configured. ' +
                        'Provide `frameworks` in the request or run `configure_compliance` first.',
                },
            ],
        };
    }
    const report = await checkCompliance(spec, frameworks);
    const lines = [
        `## Compliance Report — ${spec.id}: ${spec.title}`,
        '',
        `**Frameworks checked:** ${report.frameworks.join(', ')}`,
        `**Coverage:** ${String(report.coveragePercent)}%`,
        `**Total gaps:** ${String(report.gaps.length)}`,
        '',
    ];
    if (report.gaps.length === 0) {
        lines.push('All required compliance criteria are present. No action needed.');
    }
    else {
        lines.push('### Gaps Found', '');
        for (const gap of report.gaps) {
            const icon = gap.status === 'partial' ? '~' : 'x';
            lines.push(`- [${gap.framework.toUpperCase()}] ${icon} ${gap.criterion}`);
        }
        lines.push('');
        lines.push(`Run \`inject_criteria\` or update the spec's acceptance criteria to address these gaps.`);
    }
    return { content: [{ type: 'text', text: lines.join('\n') }] };
}
// ---------------------------------------------------------------------------
// Main dispatcher
// ---------------------------------------------------------------------------
export async function handleCheckComplianceUnified(args) {
    switch (args.mode) {
        case 'score':
            return handleScoreMode(args);
        case 'gaps':
            return Promise.resolve(handleGapsMode(args));
        case 'verify':
            return handleVerifyMode(args);
        case 'full':
            return handleFullMode(args);
    }
}
// ---------------------------------------------------------------------------
// Shims for deprecated tools (backward compatibility)
// ---------------------------------------------------------------------------
/** @deprecated Use check_compliance with mode='score' instead */
export async function handleComplianceScoreReportShim(args) {
    return handleScoreMode({ mode: 'score', ...args });
}
/** @deprecated Use check_compliance with mode='gaps' instead */
export function handleComplianceGapAnalysisShim(args) {
    return handleGapsMode({ mode: 'gaps', ...args });
}
/** @deprecated Use check_compliance with mode='verify' instead */
export async function handleVerifySpecComplianceShim(args) {
    return handleVerifyMode({ mode: 'verify', ...args });
}
/** @deprecated Use check_compliance with mode='verify' + frameworks instead */
export async function handleCheckComplianceLegacyShim(input) {
    return handleLegacyCheckMode(input);
}
//# sourceMappingURL=compliance-unified-handler.js.map