// tools/validate.ts — Compare spec vs implementation
// Uses the validator engine to check coverage, missing items, quality issues.
import { specStore, knowledgeStore } from '../storage/index.js';
import { validateSpec, generateDoR, generateDoD } from '../engine/validator.js';
import { calcQualityScore } from '../engine/auditor-scoring.js';
import { dispatchFeedbackEvent } from './learn.js';
import { t, ti } from '../i18n/index.js';
import { createBasicPhaseEvent } from '../engine/phase-tracker.js';
import { validateContractCompliance } from '../engine/test-scaffold-generator.js';
// Re-export for external use (SPEC-018)
export { validateContractCompliance };
export async function handleValidate(args) {
    const { specId, projectId } = args;
    // 1. Load spec
    const spec = await specStore.getSpec(projectId, specId);
    if (!spec) {
        return {
            content: [{ type: 'text', text: ti('spec.notFound', { id: specId }) }],
            isError: true,
        };
    }
    // 2. Load project knowledge for project path
    const knowledge = await knowledgeStore.getKnowledge(projectId);
    if (!knowledge) {
        return {
            content: [{ type: 'text', text: t('project.notFound') }],
            isError: true,
        };
    }
    const projectPath = knowledge.projectPath;
    // 3. Run validation engine
    const result = await validateSpec(spec, projectPath);
    // 4. Generate DoR and DoD checklists
    const dor = generateDoR(spec);
    const dod = await generateDoD(spec, result);
    // 5. Compute implementation quality score from validated files (SPEC-010 S47)
    const implementationQualityScore = calcQualityScore(result.qualityIssues);
    const auditedFiles = [...new Set(result.qualityIssues.map((i) => i.file))];
    // 6. Build output
    const output = {
        specId,
        title: spec.title,
        score: result.score,
        fieldsImplemented: result.fieldsImplemented,
        fieldsTotal: result.fieldsTotal,
        matches: result.matches,
        missing: result.missing,
        extra: result.extra,
        qualityIssues: result.qualityIssues.map((issue) => ({
            file: issue.file,
            line: issue.line,
            severity: issue.severity,
            rule: issue.rule,
            message: issue.message,
            suggestion: issue.suggestion,
        })),
        implementationQualityScore: {
            overall: implementationQualityScore.overall,
            gradeLetter: scoreToGrade(implementationQualityScore.overall),
            filesAudited: auditedFiles.length,
            categories: implementationQualityScore.categories.map((c) => ({
                category: c.category,
                score: c.score,
                weight: c.weight,
                issueCount: c.issueCount,
                worstSeverity: c.worstSeverity,
            })),
        },
        definitionOfReady: {
            isReady: dor.isReady,
            passed: dor.passedCount,
            required: dor.requiredCount,
            items: dor.items
                .filter((item) => item.status === 'failed')
                .map((item) => ({
                id: item.id,
                description: item.description,
                status: item.status,
            })),
        },
        definitionOfDone: {
            isDone: dod.isDone,
            passed: dod.passedCount,
            required: dod.requiredCount,
            items: dod.items
                .filter((item) => item.status !== 'passed')
                .map((item) => ({
                id: item.id,
                description: item.description,
                status: item.status,
            })),
        },
    };
    // Auto-suggest corrective actions based on validation results
    const suggestions = [];
    if (result.score < 50) {
        suggestions.push('Critical: Many acceptance criteria not implemented. Review spec requirements.');
    }
    if (result.qualityIssues.length > 10) {
        suggestions.push('Run audit for detailed code quality analysis.');
    }
    if (!dor.isReady && spec.status === 'draft') {
        suggestions.push('Spec is not ready for implementation. Complete missing DoR items first.');
    }
    if (!dod.isDone && spec.status === 'implementing') {
        suggestions.push('Implementation incomplete. Review DoD checklist before marking as done.');
    }
    if (result.missing.length > 0) {
        suggestions.push(`${result.missing.length} criteria still missing. Run detect_drift to identify gaps.`);
    }
    const outputWithSuggestions = {
        ...output,
        suggestions: suggestions.length > 0 ? suggestions : undefined,
    };
    // SPEC-012: Dispatch feedback event for auto-improvement loop (best-effort)
    void dispatchFeedbackEvent(projectId, {
        type: 'validate',
        specId,
        input: { specType: spec.type, scope: spec.scope },
        outcome: {
            score: result.score,
            missingCount: result.missing.length,
            qualityIssueCount: result.qualityIssues.length,
            dorPassed: dor.isReady,
            dodPassed: dod.isDone,
        },
        delta: { failedCriteria: output.definitionOfReady.items.map((i) => i.id) },
        timestamp: new Date().toISOString(),
    });
    // Auto-capture antipattern when quality is consistently low
    if (result.score < 70 && result.qualityIssues.length > 0) {
        const topIssueRules = [...new Set(result.qualityIssues.map((i) => i.rule))].slice(0, 5);
        void dispatchFeedbackEvent(projectId, {
            type: 'validate',
            specId,
            input: { trigger: 'auto-quality-learn', rules: topIssueRules },
            outcome: { score: result.score, antipatterns: topIssueRules },
            delta: { qualityGap: 100 - result.score },
            timestamp: new Date().toISOString(),
        });
    }
    return {
        phaseEvent: createBasicPhaseEvent('validate', 'completed', 100, 'validating'),
        content: [
            {
                type: 'text',
                text: ti('tools.validate.success', { score: String(result.score) }),
            },
            { type: 'text', text: JSON.stringify(outputWithSuggestions, null, 2) },
        ],
        structuredContent: outputWithSuggestions,
    };
}
function scoreToGrade(score) {
    if (score >= 90) {
        return 'A';
    }
    if (score >= 80) {
        return 'B';
    }
    if (score >= 70) {
        return 'C';
    }
    if (score >= 60) {
        return 'D';
    }
    return 'F';
}
//# sourceMappingURL=validate.js.map