// Planu — Spec Validator Engine
// Public orchestrator: thin entry point that delegates to internal sub-modules.
// All imports from '../engine/validator.js' continue to work unchanged.
import { extractCriteria } from './validator/extractors.js';
import { scanCodeForSpec, checkCriterion, classifyDriftSeverity, quickQualityCheck, } from './validator/analyzer.js';
// Re-export the full public API so external callers never need to know
// about the sub-module layout.
export { generateDoR, generateDoD } from './validator/dor-dod.js';
export { generateChecklist } from './validator/checklist.js';
/**
 * Validate a spec against the actual codebase.
 * Reads the spec files (HU.md, FICHA-TECNICA.md), extracts criteria,
 * then checks the filesystem/code for compliance.
 */
export async function validateSpec(spec, projectPath) {
    const criteria = await extractCriteria(spec);
    const codeState = await scanCodeForSpec(spec, projectPath);
    const matches = [];
    const missing = [];
    const extra = [];
    const qualityIssues = [];
    for (const criterion of criteria) {
        const found = await checkCriterion(criterion, projectPath, codeState);
        if (found) {
            matches.push(criterion);
        }
        else {
            missing.push(criterion);
        }
    }
    // Detect extra files not covered by spec criteria
    for (const file of codeState.unexpectedFiles) {
        extra.push(`Unexpected file: ${file}`);
    }
    // Check for basic quality issues in affected files
    for (const file of codeState.affectedFiles) {
        const issues = await quickQualityCheck(file, projectPath);
        qualityIssues.push(...issues);
    }
    const fieldsTotal = criteria.length;
    const fieldsImplemented = matches.length;
    /* v8 ignore next 1 */
    const score = fieldsTotal > 0 ? Math.round((fieldsImplemented / fieldsTotal) * 100) : 0;
    return {
        matches,
        missing,
        extra,
        fieldsImplemented,
        fieldsTotal,
        score,
        qualityIssues,
    };
}
/**
 * Detect drift between spec and current code state.
 * Returns a report with all drifts found and an overall compliance score.
 */
export async function detectDrift(spec, projectPath, _mode = 'full', threshold = 80) {
    const validation = await validateSpec(spec, projectPath);
    const drifts = [];
    // Each missing criterion is a drift
    for (const criterion of validation.missing) {
        drifts.push({
            file: '',
            specCriterion: criterion,
            expected: 'Implemented',
            actual: 'Missing',
            severity: classifyDriftSeverity(criterion),
            autoFixable: false,
        });
    }
    // Quality issues as drift items
    for (const issue of validation.qualityIssues) {
        drifts.push({
            file: issue.file,
            specCriterion: issue.rule,
            expected: issue.suggestion,
            actual: issue.message,
            /* v8 ignore next 2 */
            severity: issue.severity === 'critical' ? 'critical' : issue.severity === 'error' ? 'high' : 'medium',
            autoFixable: false,
            suggestedFix: issue.suggestion,
        });
    }
    const driftScore = validation.score;
    const isCompliant = driftScore >= threshold;
    return {
        specId: spec.id,
        checkType: 'on-demand',
        driftScore,
        drifts,
        lastChecked: new Date().toISOString(),
        isCompliant,
    };
}
//# sourceMappingURL=validator.js.map