/**
 * Confidence Score Computation
 *
 * Single function that computes a finding's confidence score from
 * baseConfidence + sum(applicable adjustments), then routes by thresholds.
 */

import type { Vulnerability } from '../shared/types'
import type {
  ConfidenceComputation,
  ConfidenceAdjustment,
  AdjustmentRule,
  AdjustmentContext,
  DepthConfig,
} from './types'

/** Default base confidence when detector doesn't set baseConfidence */
const DEFAULT_BASE_CONFIDENCE = 0.35

/**
 * Compute confidence score for a single finding.
 *
 * Logic: score = clamp(base + sum(applicable deltas), 0.0, 1.0)
 * Then route by depth thresholds:
 *   - score >= surfaceThreshold → 'surface'
 *   - score >= validateThreshold && aiEnabled → 'validate'
 *   - otherwise → 'suppress'
 */
export function computeConfidence(
  finding: Vulnerability,
  context: AdjustmentContext,
  rules: AdjustmentRule[],
  depthConfig: DepthConfig
): ConfidenceComputation {
  const base = finding.baseConfidence ?? DEFAULT_BASE_CONFIDENCE

  // Evaluate all rules and collect applicable adjustments
  const adjustments: ConfidenceAdjustment[] = []
  for (const rule of rules) {
    if (rule.applies(finding, context)) {
      adjustments.push({
        factor: rule.name,
        delta: rule.delta,
        reason: rule.reason,
        source: rule.source,
      })
    }
  }

  // Compute final score: base + sum(deltas), clamped to [0.0, 1.0]
  const totalDelta = adjustments.reduce((sum, adj) => sum + adj.delta, 0)
  const rawScore = base + totalDelta
  const score = Math.max(0.0, Math.min(1.0, rawScore))

  // Route by thresholds
  let routing: ConfidenceComputation['routing']
  if (score >= depthConfig.surfaceThreshold) {
    routing = 'surface'
  } else if (score >= depthConfig.validateThreshold && depthConfig.aiEnabled) {
    routing = 'validate'
  } else {
    routing = 'suppress'
  }

  return { score, base, adjustments, routing }
}
