/**
 * CppcheckRunner - Static analysis via cppcheck
 * DD §15. Exhaustive branch checking.
 *
 * @module packages/toolchain-cpp/src/analysis/CppcheckRunner
 */

import { execFileSync } from 'child_process'
import { DiagnosticParser, type ParsedDiagnostic } from './DiagnosticParser.js'

export interface CppcheckOutput {
  ok: boolean
  diagnostics: ParsedDiagnostic[]
  output: string
  elapsed_ms: number
}

export class CppcheckRunner {
  private parser: DiagnosticParser

  constructor() {
    this.parser = new DiagnosticParser()
  }

  run(project_root: string, options?: { enable_all?: boolean; check_config?: boolean }): CppcheckOutput {
    const start = Date.now()
    const args: string[] = ['--enable=all', '--inconclusive', '--error-exitcode=0']

    if (options?.check_config) {
      args.push('--check-config')
    }

    try {
      const output = execFileSync('cppcheck', [...args, project_root], {
        encoding: 'utf-8',
        stdio: 'pipe',
      })

      return {
        ok: true,
        diagnostics: this.parser.parse_compiler_output(output),
        output,
        elapsed_ms: Date.now() - start
      }
    } catch (error) {
      const err = error as { stdout?: string; message?: string }
      const output = err.stdout || err.message || ''
      return {
        ok: false,
        diagnostics: [],
        output,
        elapsed_ms: Date.now() - start
      }
    }
  }
}
