#!/usr/bin/env npx tsx
/**
 * Extract medium+ findings for systematic triage
 *
 * Outputs findings grouped by category with file paths for code review
 */

import * as fs from 'fs'
import * as path from 'path'
import type { ScanResult, Vulnerability } from '../../shared/types'

const RESULTS_DIR = path.join(__dirname, '../../../validation-results')
const REPOS_DIR = path.join(__dirname, '../../../validation-repos')

interface TriageFinding {
  id: string
  repo: string
  file: string
  line: number
  severity: string
  category: string
  title: string
  description: string
  lineContent: string
  codeType: 'library' | 'example' | 'test' | 'other'
}

function classifyCodeType(filePath: string): 'library' | 'example' | 'test' | 'other' {
  const lowerPath = filePath.toLowerCase()

  if (lowerPath.includes('__tests__') || lowerPath.includes('/test/') ||
      lowerPath.includes('/tests/') || lowerPath.includes('.test.') ||
      lowerPath.includes('.spec.') || lowerPath.includes('/fixtures/')) {
    return 'test'
  }

  if (lowerPath.includes('/examples/') || lowerPath.includes('/example/') ||
      lowerPath.includes('/demos/') || lowerPath.includes('/demo/') ||
      lowerPath.includes('/templates/') || lowerPath.includes('/cookbook/')) {
    return 'example'
  }

  if (lowerPath.includes('/src/') || lowerPath.includes('/lib/') ||
      lowerPath.includes('/libs/') || lowerPath.includes('/packages/')) {
    return 'library'
  }

  return 'other'
}

function extractMediumPlusFindings(): TriageFinding[] {
  const findings: TriageFinding[] = []

  const files = fs.readdirSync(RESULTS_DIR).filter(f => f.endsWith('.json'))

  for (const file of files) {
    const repoName = file.replace('-cheap.json', '').replace('-validated.json', '')
    const content = fs.readFileSync(path.join(RESULTS_DIR, file), 'utf-8')
    const result = JSON.parse(content) as ScanResult

    for (const vuln of result.vulnerabilities) {
      if (['critical', 'high', 'medium'].includes(vuln.severity)) {
        findings.push({
          id: vuln.id,
          repo: repoName,
          file: vuln.filePath,
          line: vuln.lineNumber,
          severity: vuln.severity,
          category: vuln.category,
          title: vuln.title,
          description: vuln.description,
          lineContent: vuln.lineContent,
          codeType: classifyCodeType(vuln.filePath),
        })
      }
    }
  }

  return findings
}

function groupByCategory(findings: TriageFinding[]): Map<string, TriageFinding[]> {
  const groups = new Map<string, TriageFinding[]>()

  for (const f of findings) {
    const existing = groups.get(f.category) || []
    existing.push(f)
    groups.set(f.category, existing)
  }

  return groups
}

function main() {
  const findings = extractMediumPlusFindings()
  const grouped = groupByCategory(findings)

  console.log(`\n${'='.repeat(60)}`)
  console.log('MEDIUM+ FINDINGS FOR TRIAGE')
  console.log('='.repeat(60))
  console.log(`Total: ${findings.length} findings\n`)

  // Summary by category
  console.log('By Category:')
  const sortedCategories = Array.from(grouped.entries())
    .sort((a, b) => b[1].length - a[1].length)

  for (const [category, catFindings] of sortedCategories) {
    const bySeverity = {
      critical: catFindings.filter(f => f.severity === 'critical').length,
      high: catFindings.filter(f => f.severity === 'high').length,
      medium: catFindings.filter(f => f.severity === 'medium').length,
    }
    console.log(`  ${category}: ${catFindings.length} (C:${bySeverity.critical} H:${bySeverity.high} M:${bySeverity.medium})`)
  }

  // By code type
  const byCodeType = {
    library: findings.filter(f => f.codeType === 'library').length,
    example: findings.filter(f => f.codeType === 'example').length,
    test: findings.filter(f => f.codeType === 'test').length,
    other: findings.filter(f => f.codeType === 'other').length,
  }
  console.log(`\nBy Code Type:`)
  console.log(`  Library: ${byCodeType.library}`)
  console.log(`  Example: ${byCodeType.example}`)
  console.log(`  Test: ${byCodeType.test}`)
  console.log(`  Other: ${byCodeType.other}`)

  // Output JSON for further processing
  const outputPath = path.join(RESULTS_DIR, 'medium-plus-findings.json')
  fs.writeFileSync(outputPath, JSON.stringify(findings, null, 2))
  console.log(`\nFindings exported to: ${outputPath}`)

  // Output summary by repo
  console.log('\nBy Repository:')
  const byRepo = new Map<string, number>()
  for (const f of findings) {
    byRepo.set(f.repo, (byRepo.get(f.repo) || 0) + 1)
  }
  for (const [repo, count] of byRepo) {
    console.log(`  ${repo}: ${count}`)
  }
}

main()
