/**
 * DiagnosticParser - Parses compiler output to structured diagnostics
 * DD §15. Deterministic semantic_signature generation (NO LLM here).
 *
 * @module packages/toolchain-cpp/src/analysis/DiagnosticParser
 */

import type { DiagnosticSeverity } from '@aircoding/contracts'

export interface ParsedDiagnostic {
  file?: string
  line?: number
  column?: number
  severity: DiagnosticSeverity
  message: string
  code?: string
  context?: string
  semantic_signature: string
}

export class DiagnosticParser {
  /**
   * Parse compiler output (gcc/clang) to structured Diagnostics.
   */
  parse_compiler_output(output: string): ParsedDiagnostic[] {
    const lines = output.split('\n')
    const diagnostics: ParsedDiagnostic[] = []

    // GCC/Clang diagnostic pattern: file:line:col: severity: message
    const GCC_PATTERN = /^([^:]+):(\d+):(\d+):\s*(error|warning|note|fatal error):\s*(.+)/

    for (const line of lines) {
      const match = line.match(GCC_PATTERN)
      if (match) {
        const [, file, line_str, col_str, severity_str, message] = match
        const severity = this.map_severity(severity_str)
        const sig = this.generate_signature(file, severity, message)

        diagnostics.push({
          file,
          line: parseInt(line_str),
          column: parseInt(col_str),
          severity,
          message: message.trim(),
          semantic_signature: sig
        })
      }
    }

    return diagnostics
  }

  /**
   * Generate deterministic semantic_signature for deduplication.
   */
  generate_signature(file: string, severity: DiagnosticSeverity, message: string): string {
    // Deterministic hash from error location + type + normalized message
    const normalized = message.toLowerCase().replace(/\d+/g, 'N').replace(/'[^']*'/g, "'X'").replace(/"[^"]*"/g, '"X"')
    const source = `${file}:${severity}:${normalized}`
    // Simple deterministic hash
    let hash = 0
    for (let i = 0; i < source.length; i++) {
      const char = source.charCodeAt(i)
      hash = ((hash << 5) - hash) + char
      hash |= 0
    }
    return `diag_${Math.abs(hash).toString(16).padStart(8, '0')}`
  }

  private map_severity(s: string): DiagnosticSeverity {
    switch (s.toLowerCase()) {
      case 'error':
      case 'fatal error':
        return 'error'
      case 'warning':
        return 'warning'
      case 'note':
        return 'info'
      default:
        return 'info'
    }
  }
}
