/// <reference lib="webworker" />
import createQpdfModule from '@neslinesli93/qpdf-wasm';
import wasmUrl from '@neslinesli93/qpdf-wasm/dist/qpdf.wasm?url';

interface Req {
  id: number;
  args: string[]; // qpdf argv (excluding program name); may reference /in.pdf, /out.pdf
  input: Uint8Array;
  inName?: string; // default 'in.pdf'
  outName?: string; // default 'out.pdf' — omit for commands with no file output (e.g. --check)
}

self.onmessage = async (e: MessageEvent<Req>) => {
  const { id, args, input } = e.data;
  const inName = e.data.inName ?? 'in.pdf';
  const outName = e.data.outName;
  const log: string[] = [];
  try {
    const mod: any = await createQpdfModule({
      locateFile: () => wasmUrl,
      print: (s: string) => log.push(s),
      printErr: (s: string) => log.push(s),
      noExitRuntime: true,
    } as any);
    mod.FS.writeFile('/' + inName, input);
    let code = 0;
    try {
      code = mod.callMain(args);
    } catch (err: any) {
      // Emscripten throws ExitStatus on exit(); recover the code
      if (err && typeof err.status === 'number') code = err.status;
      else throw err;
    }
    // qpdf exit codes: 0 = ok, 3 = warnings (still produced output), 2 = errors
    const ok = code === 0 || code === 3;
    let output: Uint8Array | undefined;
    if (ok && outName) {
      try { output = mod.FS.readFile('/' + outName) as Uint8Array; } catch { /* no output */ }
    }
    const buf = output ? output.slice().buffer : undefined;
    (self as any).postMessage({ id, ok, code, log: log.join('\n'), output: output ? new Uint8Array(buf!) : undefined },
      buf ? [buf] : []);
  } catch (err: any) {
    (self as any).postMessage({ id, ok: false, code: -1, log: (log.join('\n') + '\n' + (err?.message || String(err))).trim() });
  }
};
