/**
 * Postprocessing Pipeline — Runs the full postprocessing chain on findings.
 *
 * Dedup → context adjustments → contradiction resolution → suppression.
 * Records audit decisions for each sub-step via FilterPipeline.
 */

import type { Vulnerability, ScanFile } from '../shared/types'
import type { MiddlewareAuthConfig } from '../model/middleware-detector'
import type { FilterPipeline } from './filtering/pipeline'
import type { SuppressionResult } from './suppression/types'
import { deduplicateVulnerabilities } from './dedup'
import { applyContextAdjustments } from './filtering/context-adjustments'
import { resolveContradictions } from './contradictions'
import { SuppressionManager } from './suppression'

export interface PostprocessInput {
  /** Raw findings to postprocess */
  findings: Vulnerability[]
  /** Source files (for inline suppression parsing) */
  files: ScanFile[]
  /** Middleware config for contradiction resolution */
  middlewareConfig?: MiddlewareAuthConfig
  /** Project path for suppression config loading */
  projectPath?: string
  /** FilterPipeline for audit recording */
  filterPipeline: FilterPipeline
  /** Whether to show suppressed findings */
  showSuppressed?: boolean
}

export interface PostprocessResult {
  /** Findings after all postprocessing */
  findings: Vulnerability[]
  /** Suppression result (for stats and suppressed findings) */
  suppressionResult: SuppressionResult
}

const fid = (v: Pick<Vulnerability, 'filePath' | 'lineNumber' | 'category'>) =>
  `${v.filePath}:${v.lineNumber}:${v.category}`

/**
 * Run the full postprocessing chain on findings.
 *
 * Pipeline: dedup → context adjustments → contradiction resolution → suppression
 */
export function postprocessFindings(input: PostprocessInput): PostprocessResult {
  const {
    findings,
    files,
    middlewareConfig,
    projectPath,
    filterPipeline,
  } = input

  // 1. Deduplicate vulnerabilities
  const uniqueVulnerabilities = deduplicateVulnerabilities(findings)
  if (filterPipeline.isEnabled) {
    const uniqueIds = new Set(uniqueVulnerabilities.map(fid))
    for (const v of findings) {
      if (!uniqueIds.has(fid(v))) {
        filterPipeline.record(fid(v), { stage: 'deduplication', action: 'deduplicated', reason: 'Duplicate finding removed' })
      }
    }
  }

  // 2. Apply file context-based severity adjustments (Phase 2b)
  const contextAdjustedVulnerabilities = applyContextAdjustments(uniqueVulnerabilities)
  if (filterPipeline.isEnabled) {
    for (let i = 0; i < uniqueVulnerabilities.length; i++) {
      const before = uniqueVulnerabilities[i]
      const after = contextAdjustedVulnerabilities[i]
      if (before.severity !== after.severity) {
        filterPipeline.record(fid(after), { stage: 'global_context', action: 'downgraded', reason: after.validationNotes || 'Context-based severity downgrade', originalSeverity: before.severity, newSeverity: after.severity })
      }
    }
  }

  // 3. Resolve contradictions
  const resolvedVulnerabilities = resolveContradictions(contextAdjustedVulnerabilities, middlewareConfig)
  if (filterPipeline.isEnabled) {
    const resolvedIds = new Set(resolvedVulnerabilities.map(fid))
    for (const v of contextAdjustedVulnerabilities) {
      if (!resolvedIds.has(fid(v))) {
        filterPipeline.record(fid(v), { stage: 'contradiction_resolution', action: 'dismissed', reason: 'Removed by contradiction resolution' })
      }
    }
    for (let i = 0; i < contextAdjustedVulnerabilities.length; i++) {
      const before = contextAdjustedVulnerabilities[i]
      const after = resolvedVulnerabilities.find(v => fid(v) === fid(before))
      if (after && before.severity !== after.severity) {
        filterPipeline.record(fid(after), { stage: 'contradiction_resolution', action: 'downgraded', reason: 'Downgraded by contradiction resolution', originalSeverity: before.severity, newSeverity: after.severity })
      }
    }
  }

  // 4. Apply suppressions (inline comments + config file)
  const resolvedProjectPath = projectPath || process.cwd()
  const suppressionManager = new SuppressionManager({ projectPath: resolvedProjectPath })
  const suppressionResult = suppressionManager.applySuppressions(resolvedVulnerabilities, files)

  if (filterPipeline.isEnabled) {
    for (const s of suppressionResult.suppressed) {
      filterPipeline.record(fid(s.vulnerability), { stage: 'user_suppression', action: 'suppressed', reason: s.suppression.reason || `Suppressed by ${s.suppression.type}` })
    }
  }

  return {
    findings: suppressionResult.findings,
    suppressionResult,
  }
}

// Re-export sub-modules for direct access
export { deduplicateVulnerabilities } from './dedup'
export { aggregateNoisyFindings } from './aggregation'
export { resolveContradictions } from './contradictions'
export { capValidationCandidatesPerFile, MAX_VALIDATION_CANDIDATES_PER_FILE } from './validation-cap'
