// engine/paradigm-advisor/recommendations.ts — Paradigm recommendations and formatter (SPEC-035b)
import { MIN_CONFIDENCE_FOR_RECOMMENDATIONS, MIN_CONFIDENCE_FOR_DRIFT, OOP_KEYWORDS, FP_KEYWORDS, RECOMMENDATIONS_BY_PARADIGM, GENERIC_RECOMMENDATIONS, MIGRATION_PHASES, MIGRATION_RISKS, } from './tables.js';
// === Recommendations ===
/**
 * Returns paradigm-specific recommendations based on a detection report.
 * Returns an empty array when confidence is below threshold (avoids noise).
 */
export function getParadigmRecommendations(detection) {
    const dominant = detection.dominant;
    if (!dominant || dominant.confidence < MIN_CONFIDENCE_FOR_RECOMMENDATIONS) {
        return [];
    }
    const known = RECOMMENDATIONS_BY_PARADIGM[dominant.paradigmId];
    if (known) {
        return known;
    }
    return GENERIC_RECOMMENDATIONS;
}
// === Drift detection ===
/**
 * Detects paradigm drift by checking if spec content contains keywords
 * inconsistent with the dominant paradigm.
 */
export function detectParadigmDrift(specContent, dominantParadigm, threshold) {
    if (!specContent || threshold < 0 || threshold > 1) {
        return null;
    }
    const lower = specContent.toLowerCase();
    const evidence = [];
    if (dominantParadigm === 'functional' || dominantParadigm === 'pure-functional') {
        for (const kw of OOP_KEYWORDS) {
            if (lower.includes(kw)) {
                evidence.push(kw.trim());
            }
        }
        if (evidence.length === 0) {
            return null;
        }
        const driftScore = evidence.length / (evidence.length + FP_KEYWORDS.length);
        if (driftScore < threshold) {
            return null;
        }
        return {
            expectedParadigm: dominantParadigm,
            detectedParadigm: 'oop',
            evidence,
            severity: driftScore > 0.7 ? 'blocker' : 'warning',
        };
    }
    if (dominantParadigm === 'oop') {
        for (const kw of FP_KEYWORDS) {
            if (lower.includes(kw)) {
                evidence.push(kw.trim());
            }
        }
        if (evidence.length === 0) {
            return null;
        }
        const driftScore = evidence.length / (evidence.length + OOP_KEYWORDS.length);
        if (driftScore < threshold) {
            return null;
        }
        return {
            expectedParadigm: 'oop',
            detectedParadigm: 'functional',
            evidence,
            severity: driftScore > 0.7 ? 'blocker' : 'warning',
        };
    }
    return null;
}
// === Migration plan ===
/**
 * Generates a structured migration plan from one paradigm to another.
 */
export function generateParadigmMigrationPlan(origin, destination) {
    const key = `${origin}->${destination}`;
    const phases = MIGRATION_PHASES[key] ?? [
        'Audit the current codebase and identify hotspots',
        'Define target patterns and document them as ADRs',
        'Refactor incrementally — one module at a time',
        'Update tests to reflect new paradigm conventions',
        'Validate with the team and iterate',
    ];
    const risks = MIGRATION_RISKS[key] ?? [
        'Mixed paradigm period creates inconsistency',
        'Team alignment may slow the migration',
        'Legacy integrations may resist the new paradigm',
    ];
    const sameFamily = (origin.includes('functional') && destination.includes('functional')) ||
        (origin === 'oop' && destination === 'oop');
    const estimatedEffort = sameFamily
        ? '1-2 weeks (paradigms share many patterns)'
        : phases.length <= 4
            ? '2-4 weeks (moderate structural changes)'
            : '4-8 weeks (significant architectural shift)';
    return { origin, destination, phases, risks, estimatedEffort };
}
// === Formatter ===
/**
 * Formats paradigm recommendations and an optional drift result into a
 * human-readable expert voice section string.
 */
export function formatParadigmObservations(recommendations, drift) {
    const lines = [];
    if (recommendations.length === 0 && !drift) {
        return '';
    }
    lines.push('### Paradigm Expert Voice');
    lines.push('');
    if (drift) {
        lines.push(`**Paradigm Drift Detected** (${drift.severity.toUpperCase()}): ` +
            `Expected \`${drift.expectedParadigm}\` patterns but found \`${drift.detectedParadigm}\` signals.`);
        lines.push(`Evidence: ${drift.evidence.join(', ')}`);
        lines.push('');
    }
    if (recommendations.length > 0) {
        lines.push('**Recommendations:**');
        for (const rec of recommendations) {
            const urgencyTag = rec.urgency === 'high' ? ' [HIGH]' : rec.urgency === 'medium' ? ' [MEDIUM]' : '';
            lines.push(`- ${rec.message}${urgencyTag}`);
            if (rec.alternatives.length > 0) {
                lines.push(`  Alternatives: ${rec.alternatives.join(' | ')}`);
            }
        }
    }
    return lines.join('\n');
}
// === Threshold accessors (exposed for tests) ===
export function getMinConfidenceThreshold() {
    return MIN_CONFIDENCE_FOR_RECOMMENDATIONS;
}
export function getDriftConfidenceThreshold() {
    return MIN_CONFIDENCE_FOR_DRIFT;
}
//# sourceMappingURL=recommendations.js.map