// Minimum occurrences of a failure pattern before auto-adjusting (conservative rule)
const MIN_PATTERN_OCCURRENCES = 5;
// Sliding window size for trend calculation
const WINDOW_SIZE = 10;
// ---------------------------------------------------------------------------
// getTrend
// ---------------------------------------------------------------------------
export function getTrend(history) {
    if (history.length < 2) {
        return 'stable';
    }
    const recent = history[history.length - 1];
    const prev = history[history.length - 2];
    /* v8 ignore next 3 */
    if (recent === undefined || prev === undefined) {
        return 'stable';
    }
    const delta = recent - prev;
    if (delta > 2) {
        return 'improving';
    }
    if (delta < -2) {
        return 'degrading';
    }
    return 'stable';
}
// ---------------------------------------------------------------------------
// buildTrendMetric
// ---------------------------------------------------------------------------
export function buildTrendMetric(history) {
    const window = history.slice(-WINDOW_SIZE);
    const current = window[window.length - 1] ?? 100;
    const previous = window[window.length - 2] ?? current;
    return {
        current,
        previous,
        trend: getTrend(window),
        history: window,
        windowSize: WINDOW_SIZE,
    };
}
// ---------------------------------------------------------------------------
// analyzeValidationResults
// ---------------------------------------------------------------------------
export function analyzeValidationResults(failures) {
    const counts = new Map();
    for (const f of failures) {
        const existing = counts.get(f.criterionId);
        if (existing) {
            existing.count += 1;
            if (existing.specType !== f.specType) {
                existing.specType = 'all';
            }
        }
        else {
            counts.set(f.criterionId, { count: 1, specType: f.specType });
        }
    }
    return [...counts.entries()]
        .map(([criterion, { count, specType }]) => ({ criterion, occurrences: count, specType }))
        .sort((a, b) => b.occurrences - a.occurrences);
}
// ---------------------------------------------------------------------------
// adjustTemplate
// ---------------------------------------------------------------------------
export function adjustTemplate(specType, patterns) {
    const significant = patterns.filter((p) => p.occurrences >= MIN_PATTERN_OCCURRENCES && (p.specType === specType || p.specType === 'all'));
    if (significant.length === 0) {
        return null;
    }
    const topPattern = significant[0];
    /* v8 ignore next 3 */
    if (!topPattern) {
        return null;
    }
    return {
        id: `template-${specType}-${topPattern.criterion}-${Date.now().toString(36)}`,
        target: 'template',
        action: 'adjust_priority',
        data: {
            specType,
            criterion: topPattern.criterion,
            occurrences: topPattern.occurrences,
            requiredCriteria: significant.map((p) => p.criterion),
        },
        reason: `Criterion "${topPattern.criterion}" failed ${topPattern.occurrences} times in ${specType} specs`,
        appliedAt: new Date().toISOString(),
        reversible: true,
    };
}
// ---------------------------------------------------------------------------
// adjustRecommendationRanking
// ---------------------------------------------------------------------------
export function adjustRecommendationRanking(tools, preferences) {
    const prefMap = new Map(preferences.map((p) => [p.tool, p]));
    const rankings = new Map();
    for (const tool of tools) {
        const pref = prefMap.get(tool);
        if (!pref) {
            rankings.set(tool, 0);
            continue;
        }
        // accepted +1 per accept, rejected -2 per reject, ignored -0.5 per ignore
        let score;
        if (pref.action === 'accepted') {
            score = pref.count * 1;
        }
        else if (pref.action === 'rejected') {
            score = pref.count * -2;
        }
        else {
            score = pref.count * -0.5;
        }
        rankings.set(tool, score);
    }
    return rankings;
}
// ---------------------------------------------------------------------------
// getImprovementMetrics
// ---------------------------------------------------------------------------
export function getImprovementMetrics(calibrationHistory) {
    const accuracyHistory = calibrationHistory.map((m) => {
        const ratio = m.actualHours > 0 ? m.estimatedHours / m.actualHours : 1;
        const deviation = Math.abs(ratio - 1);
        return Math.max(0, Math.round((1 - deviation) * 100));
    });
    const completenessHistory = calibrationHistory.map((m) => m.specCompleteness);
    const driftHistory = calibrationHistory.map((m) => m.driftCount === 0 ? 100 : Math.max(0, Math.round(100 - m.driftCount * 10)));
    return {
        estimationAccuracy: buildTrendMetric(accuracyHistory),
        specCompleteness: buildTrendMetric(completenessHistory),
        driftPrevention: buildTrendMetric(driftHistory),
        totalSpecsAnalyzed: calibrationHistory.length,
        lastAnalyzedAt: new Date().toISOString(),
    };
}
//# sourceMappingURL=self-improver.js.map