import test from 'node:test'
import assert from 'node:assert/strict'
import fs from 'node:fs'
import os from 'node:os'
import path from 'node:path'
import { normalizeLocalRuntimeDiagnostic, prepareLocalRuntimeArgs, streamLocalRuntime } from './runtime-registry.js'

test('Codex startup skill-loader noise is hidden while current-request failures remain visible', () => {
  assert.equal(normalizeLocalRuntimeDiagnostic('WARN codex_core_skills::loader: ignoring icon'), '')
  assert.equal(normalizeLocalRuntimeDiagnostic('ERROR codex_core::session::session: failed to load skill broken/SKILL.md'), '')
  assert.equal(normalizeLocalRuntimeDiagnostic('Skill descriptions were shortened to fit the 2% skills context budget.'), '')
  assert.match(normalizeLocalRuntimeDiagnostic('stream disconnected - retrying sampling request'), /stream disconnected/)
})

test('prepareLocalRuntimeArgs enables Codex JSONL exactly once', () => {
  assert.deepEqual(prepareLocalRuntimeArgs({
    runtimeRow: { code: 'local-codex', local_command: 'codex' },
    args: ['exec', '--skip-git-repo-check', '-'],
  }), ['exec', '--json', '--skip-git-repo-check', '-'])

  assert.deepEqual(prepareLocalRuntimeArgs({
    runtimeRow: { code: 'local-codex', local_command: 'codex' },
    args: ['exec', '--json', '-'],
  }), ['exec', '--json', '-'])
})

test('streamLocalRuntime yields stdout before the child process closes', async () => {
  const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'aipros-local-stream-'))
  const marker = path.join(dir, 'closed.txt')
  const script = [
    "process.stdout.write('first')",
    `setTimeout(() => { process.stdout.write('second'); require('node:fs').writeFileSync(${JSON.stringify(marker)}, 'done') }, 120)`,
  ].join(';')
  const events = []

  for await (const event of streamLocalRuntime({
    runtimeRow: {
      code: 'local-test',
      local_command: process.execPath,
      local_args_json: JSON.stringify(['-e', script]),
      timeout_ms: 5000,
    },
    prompt: 'test',
    workdir: dir,
  })) {
    events.push(event)
    if (event.t === 'delta' && event.v === 'first') {
      assert.equal(fs.existsSync(marker), false)
    }
  }

  assert.deepEqual(events.filter(event => event.t === 'delta').map(event => event.v), ['first', 'second'])
  assert.equal(fs.readFileSync(marker, 'utf8'), 'done')
})

test('streamLocalRuntime forwards stderr chunks as warnings', async () => {
  const events = []
  for await (const event of streamLocalRuntime({
    runtimeRow: {
      code: 'local-test',
      local_command: process.execPath,
      local_args_json: JSON.stringify(['-e', "process.stderr.write('checking'); process.stdout.write('done')"]),
      timeout_ms: 5000,
    },
    prompt: 'test',
    workdir: process.cwd(),
  })) events.push(event)

  assert.ok(events.some(event => event.t === 'warning' && event.v === 'checking'))
  assert.ok(events.some(event => event.t === 'delta' && event.v === 'done'))
})
