/**
 * A1 regression: command injection fix — execFileSync, not execSync
 * Verifies CMakeConfigurator, CppBuilder, CppcheckRunner use execFileSync.
 */

import { describe, it, expect } from 'bun:test'
import { readFileSync } from 'fs'
import { join } from 'path'

const SRC_ROOT = join(import.meta.dir, '..', 'src')

function reads_file(relative: string): string {
  return readFileSync(join(SRC_ROOT, relative), 'utf-8')
}

describe('A1: Command injection fix', () => {
  it('CMakeConfigurator uses execFileSync, not execSync', () => {
    const src = reads_file('build/CMakeConfigurator.ts')
    expect(src).toContain('execFileSync')
    expect(src).not.toMatch(/\bexecSync\s*\(/)
  })

  it('CppBuilder uses execFileSync, not execSync', () => {
    const src = reads_file('build/CppBuilder.ts')
    expect(src).toContain('execFileSync')
    expect(src).not.toMatch(/\bexecSync\s*\(/)
  })

  it('CppcheckRunner uses execFileSync, not execSync', () => {
    const src = reads_file('analysis/CppcheckRunner.ts')
    expect(src).toContain('execFileSync')
    expect(src).not.toMatch(/\bexecSync\s*\(/)
  })

  it('CMakeConfigurator passes args as array to execFileSync', () => {
    const src = reads_file('build/CMakeConfigurator.ts')
    expect(src).toMatch(/execFileSync\s*\(\s*'cmake'/)
    expect(src).not.toMatch(/execFileSync\s*\(\s*'cmake'\s*,\s*[`'"]/)
  })

  it('CppBuilder passes args as array to execFileSync', () => {
    const src = reads_file('build/CppBuilder.ts')
    expect(src).toMatch(/execFileSync\s*\(\s*'cmake'/)
    expect(src).not.toMatch(/execFileSync\s*\(\s*'cmake'\s*,\s*[`'"]/)
  })
})
