import { readFileSync, writeFileSync, mkdirSync } from 'node:fs'
import { resolve } from 'node:path'
import { spawnSync } from 'node:child_process'

const root = resolve(import.meta.dirname, '..')
const npmw = resolve(root, 'npmw')
const packageJson = JSON.parse(readFileSync(resolve(root, 'package.json'), 'utf8'))
const scripts = packageJson.scripts ?? {}

const laneArg = process.argv.find((arg) => arg.startsWith('--lane='))
const requestedLane = laneArg ? laneArg.slice('--lane='.length) : 'all'
const validLanes = new Set(['all', 'chrome', 'oracle', 'wasm'])
if (!validLanes.has(requestedLane)) {
  throw new Error(`Unknown lane "${requestedLane}". Expected one of: ${[...validLanes].join(', ')}`)
}

const chromeTests = Object.keys(scripts)
  .filter((name) => name.startsWith('test:chrome-'))
  .sort()

const wasmBuilds = process.env.CI_REAL_REBUILD_WASM === '1'
  ? ['fetch:freecad-source', 'build:occt-history', 'build:planegcs']
  : []
if (wasmBuilds.length > 0) {
  for (const variable of ['OCCT_SOURCE_DIR', 'EMSDK']) {
    if (!process.env[variable]) throw new Error(`CI_REAL_REBUILD_WASM=1 requires ${variable} to be configured.`)
  }
}

const lanes = {
  chrome: [
    'build',
    ...chromeTests,
    ...chromeTests
      .map((name) => `check:${name.slice('test:'.length)}`)
      .filter((name) => scripts[name]),
  ],
  oracle: [
    'fetch:freecad-source',
    'configure:freecad-native',
    'build:freecad-native',
    'probe:freecad-reference',
    'test:golden:freecad',
    'test:golden:freecad:families',
    'test:golden:freecad:failures',
    'test:golden:freecad:family-failures',
    'probe:freecad-sketcher-constraints',
    'probe:freecad-partdesign-profiles',
    'probe:freecad-partdesign-base',
    'probe:freecad-partdesign-loft',
    'probe:freecad-partdesign-dressup',
    'probe:freecad-partdesign-transform',
    'probe:freecad-partdesign-failures',
    'probe:freecad-partdesign-revolution-groove',
    'probe:freecad-part-builders',
    'probe:freecad-composite-history-elementmap',
    'check:freecad-oracle-coverage',
    'check:freecad-golden-coverage',
    'check:freecad-sketcher-constraints',
    'check:freecad-fcstd-roundtrip',
    'check:freecad-composite-history-elementmap',
    'check:freecad-exact-history-elementmap-gate',
    'check:freecad-native-naming-evidence',
  ],
  wasm: [
    ...wasmBuilds,
    'check:occt-history-artifact',
    'test:browser-occt',
    'check:browser-occt',
    'test:planegcs',
    'check:planegcs-artifact',
    'test:chrome-planegcs',
    'test:chrome-native-history',
    'test:chrome-camotics-wasm',
    'test:chrome-cam-native-simulation',
    'check:chrome-planegcs',
    'check:chrome-native-history',
    'check:chrome-camotics-wasm',
    'check:chrome-cam-native-simulation',
  ],
}

const selectedLanes = requestedLane === 'all' ? ['oracle', 'wasm', 'chrome'] : [requestedLane]
const results = []

function runScript(name) {
  if (!scripts[name]) throw new Error(`Required npm script is missing: ${name}`)
  const startedAt = Date.now()
  console.log(`\n[real-verification] ${name}`)
  const result = spawnSync(npmw, ['run', name], {
    cwd: root,
    env: { ...process.env, CI_REAL_VERIFICATION: '1' },
    stdio: 'inherit',
  })
  const record = { script: name, status: result.status ?? 1, durationMs: Date.now() - startedAt }
  results.push(record)
  if (record.status !== 0) throw new Error(`Real verification failed in ${name} (exit ${record.status})`)
}

try {
  for (const lane of selectedLanes) {
    console.log(`\n[real-verification] lane=${lane}`)
    for (const name of lanes[lane]) runScript(name)
  }
} finally {
  const outputDir = resolve(root, '.cache', 'ci')
  mkdirSync(outputDir, { recursive: true })
  writeFileSync(resolve(outputDir, 'real-verification.json'), `${JSON.stringify({ generatedAt: new Date().toISOString(), lanes: selectedLanes, results }, null, 2)}\n`)
}

console.log(`\n[real-verification] completed ${results.length} commands across ${selectedLanes.join(', ')}.`)
