/**
 * Confidence Scorer
 *
 * Fuses multiple signals into a per-change confidence score
 * to determine AI generation likelihood and review requirements.
 *
 * @module scanners/ai-code/confidence-scorer
 */
const CONFIDENCE_WEIGHTS = {
    high: 30,
    medium: 15,
    low: 5,
    uncertain: 2,
};
const HALLUCINATION_WEIGHTS = {
    critical: 40,
    high: 25,
    medium: 12,
    low: 5,
};
export function scoreChange(input, config) {
    const { indicators, hallucinations } = input;
    let aiLikelihood = 0;
    for (const indicator of indicators) {
        aiLikelihood += CONFIDENCE_WEIGHTS[indicator.confidence];
    }
    for (const hallucination of hallucinations) {
        aiLikelihood += HALLUCINATION_WEIGHTS[hallucination.severity] ?? 10;
    }
    aiLikelihood = Math.min(100, aiLikelihood);
    const confidence = determineConfidence(aiLikelihood, indicators.length);
    const requireForConfidence = config?.review?.requireForConfidence ?? "medium";
    const requireForHallucinations = config?.review?.requireForHallucinations ?? true;
    const autoApproveBelow = config?.review?.autoApproveBelow ?? 30;
    const confidenceOrder = ["high", "medium", "low", "uncertain"];
    const confidenceThresholdMet = confidenceOrder.indexOf(confidence) <= confidenceOrder.indexOf(requireForConfidence);
    const hasHallucinations = hallucinations.length > 0;
    const requiresReview = (confidenceThresholdMet && aiLikelihood >= autoApproveBelow) ||
        (requireForHallucinations && hasHallucinations);
    let reviewReason;
    if (requiresReview) {
        if (hasHallucinations && requireForHallucinations) {
            reviewReason = `${hallucinations.length} hallucination(s) detected`;
        }
        else if (confidenceThresholdMet) {
            reviewReason = `AI likelihood ${aiLikelihood}% with ${confidence} confidence`;
        }
    }
    return {
        ...input,
        aiLikelihood,
        confidence,
        requiresReview,
        reviewReason,
    };
}
function determineConfidence(aiLikelihood, indicatorCount) {
    if (aiLikelihood >= 70 && indicatorCount >= 3)
        return "high";
    if (aiLikelihood >= 40 && indicatorCount >= 2)
        return "medium";
    if (aiLikelihood >= 15 || indicatorCount >= 1)
        return "low";
    return "uncertain";
}
export function scoreAllChanges(changes, config) {
    const scoredChanges = changes.map((c) => scoreChange(c, config));
    const aiThreshold = config?.review?.autoApproveBelow ?? 30;
    const aiLikelyChanges = scoredChanges.filter((c) => c.aiLikelihood >= aiThreshold).length;
    const requiresReview = scoredChanges.filter((c) => c.requiresReview).length;
    const hallucinationsFound = scoredChanges.reduce((sum, c) => sum + c.hallucinations.length, 0);
    const averageConfidence = scoredChanges.length > 0
        ? scoredChanges.reduce((sum, c) => sum + c.aiLikelihood, 0) /
            scoredChanges.length
        : 0;
    return {
        scoredChanges,
        summary: {
            totalChanges: scoredChanges.length,
            aiLikelyChanges,
            requiresReview,
            hallucinationsFound,
            averageConfidence: Math.round(averageConfidence * 10) / 10,
        },
    };
}
export function calculateDetectionScore(scoredChanges) {
    if (scoredChanges.length === 0)
        return 100;
    const avgLikelihood = scoredChanges.reduce((sum, c) => sum + c.aiLikelihood, 0) /
        scoredChanges.length;
    return Math.round(100 - avgLikelihood);
}
export function calculateHallucinationScore(scoredChanges) {
    const allHallucinations = scoredChanges.flatMap((c) => c.hallucinations);
    if (allHallucinations.length === 0)
        return 100;
    let penalty = 0;
    for (const h of allHallucinations) {
        penalty += HALLUCINATION_WEIGHTS[h.severity] ?? 10;
    }
    return Math.max(0, Math.round(100 - penalty));
}
export function calculateReviewScore(scoredChanges) {
    if (scoredChanges.length === 0)
        return 100;
    const reviewRequired = scoredChanges.filter((c) => c.requiresReview).length;
    const reviewRate = reviewRequired / scoredChanges.length;
    return Math.round((1 - reviewRate) * 100);
}
export function calculateOverallScore(scores) {
    const weights = {
        detection: 0.3,
        hallucination: 0.5,
        review: 0.2,
    };
    return Math.round(scores.detectionScore * weights.detection +
        scores.hallucinationScore * weights.hallucination +
        scores.reviewScore * weights.review);
}
export function determineReviewPriority(change) {
    if (!change.requiresReview)
        return "none";
    const hasCriticalHallucination = change.hallucinations.some((h) => h.severity === "critical");
    if (hasCriticalHallucination)
        return "critical";
    const hasHighHallucination = change.hallucinations.some((h) => h.severity === "high");
    if (hasHighHallucination || change.confidence === "high")
        return "high";
    if (change.confidence === "medium")
        return "medium";
    return "low";
}
export function groupByReviewPriority(scoredChanges) {
    const groups = {
        critical: [],
        high: [],
        medium: [],
        low: [],
        none: [],
    };
    for (const change of scoredChanges) {
        const priority = determineReviewPriority(change);
        groups[priority].push(change);
    }
    return groups;
}
//# sourceMappingURL=confidence-scorer.js.map