/** Sync-worker plumbing smoke test: spawn → init handshake → generic RPC
 *  round-trip → event-proxy sanity. Does NOT exercise live IMAP. */
import fs from "node:fs";
import path from "node:path";
import os from "node:os";
import { spawnSyncWorker } from "../packages/mailx-service/index.js";
import { MailxDB } from "../packages/mailx-store/index.js";

const liveDir = path.join(os.homedir(), ".rmfmail");
const tmp = fs.mkdtempSync(path.join(os.tmpdir(), "rmf-syncw-"));
const tmpStore = path.join(tmp, "store");
fs.mkdirSync(tmpStore, { recursive: true });
for (const s of ["", "-wal", "-shm"]) {
    const src = path.join(liveDir, "mailx.db" + s);
    if (fs.existsSync(src)) try { fs.copyFileSync(src, path.join(tmp, "mailx.db" + s)); } catch {}
}
let fail = 0;
const ok = (m) => console.log("  ✓", m);
const bad = (m) => { console.error("  ✗", m); fail++; };

// Main builds the schema first (worker opens with skipMigrations).
new MailxDB(tmp);
console.log("\nsync-worker smoke test");

let synced;
try {
    synced = await spawnSyncWorker({ configDir: tmp, storePath: tmpStore });
    ok("spawned + init-ok handshake");
} catch (e) { bad(`spawn failed: ${e.message}`); process.exit(1); }

// Event proxy: local on/emit must work (bin's forwarders rely on this).
let got = null;
synced.proxy.on("smokeTest", (a) => { got = a; });
synced.proxy.emit("smokeTest", 42);
await new Promise(r => setTimeout(r, 20));
if (got === 42) ok("proxy is a working EventEmitter (local on/emit)");
else bad(`local event did not fire (got ${got})`);

// Generic RPC round-trip: getDiagnosticsSnapshot needs no network.
try {
    const snap = await synced.proxy.getDiagnosticsSnapshot();
    if (snap && typeof snap === "object") ok(`RPC round-trip: getDiagnosticsSnapshot → ${Object.keys(snap).length} keys`);
    else bad(`getDiagnosticsSnapshot returned ${typeof snap}`);
} catch (e) { bad(`getDiagnosticsSnapshot RPC threw: ${e.message}`); }

// getOutboxStatus round-trip (outbox lives in the worker now).
try {
    const ob = await synced.proxy.getOutboxStatus();
    ok(`RPC round-trip: getOutboxStatus → ${JSON.stringify(ob).slice(0, 80)}`);
} catch (e) { bad(`getOutboxStatus RPC threw: ${e.message}`); }

// Unknown method → clean error, not a hang.
try {
    await synced.proxy.__definitelyNotARealMethod__();
    bad("unknown method should have thrown");
} catch (e) { ok(`unknown method rejected cleanly: ${e.message.slice(0, 60)}`); }

await synced.close();
console.log(`\n${fail ? "RESULT: FAIL" : "RESULT: PASS"}\n`);
process.exit(fail ? 1 : 0);
