/**
 * Validation Cap — Per-file cap on AI validation candidates for cost control.
 *
 * Prioritizes findings by confidence score, severity, and category importance.
 */

import type { Vulnerability } from '../shared/types'
import type { ScoredFinding } from '../score'
import { severityRank } from '../shared/parsed-file'

/** Maximum candidates per file to send to AI validation (cost control) */
export const MAX_VALIDATION_CANDIDATES_PER_FILE = 10

/**
 * Cap validation candidates per file to control AI costs
 * Prioritizes by:
 * 1. Confidence score (higher score = more likely a real finding)
 * 2. Severity (critical > high > medium > low > info)
 * 3. Category importance (secrets/URLs/auth before cosmetic patterns)
 */
export function capValidationCandidatesPerFile(
  vulnerabilities: Vulnerability[],
  maxPerFile: number = MAX_VALIDATION_CANDIDATES_PER_FILE
): Vulnerability[] {
  // Group by file
  const byFile = new Map<string, Vulnerability[]>()
  for (const vuln of vulnerabilities) {
    const existing = byFile.get(vuln.filePath) || []
    existing.push(vuln)
    byFile.set(vuln.filePath, existing)
  }

  const result: Vulnerability[] = []

  for (const [, fileVulns] of byFile) {
    // Sort by priority: confidence score descending, then severity, then category
    const sorted = [...fileVulns].sort((a, b) => {
      // Confidence score comparison (higher = higher priority for validation)
      const aScore = (a as ScoredFinding).confidence_score?.score ?? (a.baseConfidence ?? 0.35)
      const bScore = (b as ScoredFinding).confidence_score?.score ?? (b.baseConfidence ?? 0.35)
      const scoreDiff = bScore - aScore
      if (Math.abs(scoreDiff) > 0.01) return scoreDiff

      // Severity comparison (higher severity = higher priority)
      const severityDiff = severityRank(b.severity) - severityRank(a.severity)
      if (severityDiff !== 0) return severityDiff

      // Category importance (secrets/URLs/auth before AI patterns)
      const categoryPriority = (v: Vulnerability): number => {
        if (v.category === 'hardcoded_secret') return 10
        if (v.category === 'high_entropy_string') return 9
        if (v.category === 'sensitive_url') return 8
        if (v.category === 'missing_auth') return 7
        if (v.category === 'ai_pattern') return 3
        return 5
      }
      return categoryPriority(b) - categoryPriority(a)
    })

    // Take top N per file
    const capped = sorted.slice(0, maxPerFile)
    result.push(...capped)
  }

  return result
}
