import assert from 'node:assert/strict';
import { spawn } from 'node:child_process';
import { mkdtemp, copyFile, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import { join, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { once } from 'node:events';
const source = dirname(fileURLToPath(import.meta.url));
const work = await mkdtemp(join(tmpdir(), 'jam-clean-docs-'));
let server;
try {
  for (const f of ['local-events-server.mjs', 'accept-event.mjs']) await copyFile(join(source,f),join(work,f));
  server = spawn(process.execPath, ['local-events-server.mjs','0'], { cwd: work, stdio:['ignore','pipe','pipe'] });
  const base = await new Promise((resolve,reject) => {
    const timeout = setTimeout(()=>reject(Error('server startup timeout')),3000);
    server.once('error', e=>{clearTimeout(timeout);reject(e);});
    server.once('exit', code=>{clearTimeout(timeout);reject(Error(`server exited ${code}`));});
    let text='';
    server.stdout.on('data', chunk=>{text+=chunk;const m=text.match(/http:\/\/127\.0\.0\.1:\d+/);if(m){clearTimeout(timeout);resolve(m[0]);}});
  });
  const run = (url) => new Promise((resolve,reject)=> {
    const child=spawn(process.execPath,['accept-event.mjs',url],{cwd:work,stdio:['ignore','pipe','pipe']});
    let output='';child.stdout.on('data',b=>output+=b);child.once('error',reject);
    child.once('exit',code=>resolve({code,output}));
  });
  const first=await run(base);assert.equal(first.code,0);const a=JSON.parse(first.output);assert.equal(a.status,'accepted');
  const replay=await run(base);assert.equal(replay.code,0);assert.equal(JSON.parse(replay.output).event_id,a.event_id);
  const remote=await run('https://example.com');assert.notEqual(remote.code,0);
  const unauthorized=await fetch(base+'/v1/events/evt_1');assert.equal(unauthorized.status,401);
  server.kill();await once(server,'exit');server=null;
  const stopped=await run(base);assert.notEqual(stopped.code,0);
  process.stdout.write(JSON.stringify({node:process.version,passed:5,checks:['clean-directory success without dependencies','second client run retains receipt','remote host rejected before request','missing credential rejected','stopped server does not report success']},null,2)+'\n');
} finally {
  if(server){server.kill();await once(server,'exit');}
  await rm(work,{recursive:true,force:true});
}
