const assert = require("assert");
const fs = require("fs");
const os = require("os");
const path = require("path");
const { Worker } = require("worker_threads");
const {
  writeJsonAtomicSync,
  clearSafeFileDiagnostics,
  getSafeFileDiagnostics
} = require("../src/services/safe-files");

async function run() {
  const directory = fs.mkdtempSync(path.join(os.tmpdir(), "lumi-safe-files-"));
  const target = path.join(directory, "runtime_state.json");
  const originalRename = fs.renameSync;
  try {
    fs.writeFileSync(target, '{"state":"original"}\n');
    const stale = `${target}.tmp`;
    fs.writeFileSync(stale, "stale");
    const old = new Date(Date.now() - 2 * 60 * 60 * 1000);
    fs.utimesSync(stale, old, old);

    clearSafeFileDiagnostics();
    let transientFailures = 0;
    fs.renameSync = (from, to) => {
      if (to === target && String(from).endsWith(".tmp") && transientFailures < 2) {
        transientFailures += 1;
        throw Object.assign(new Error("temporarily locked"), { code: transientFailures === 1 ? "EPERM" : "EACCES" });
      }
      return originalRename(from, to);
    };
    writeJsonAtomicSync(target, { state: "recovered" }, { attempts: 4, delayMs: 1, staleTempAgeMs: 1000 });
    assert.deepEqual(JSON.parse(fs.readFileSync(target, "utf8")), { state: "recovered" });
    assert.equal(fs.existsSync(stale), false);
    assert(getSafeFileDiagnostics().filter((entry) => entry.operation === "rename").length >= 2);

    fs.writeFileSync(target, '{"state":"must-survive"}\n');
    fs.renameSync = (from, to) => {
      if (to === target && String(from).endsWith(".tmp")) {
        throw Object.assign(new Error("replacement locked"), { code: "EPERM" });
      }
      return originalRename(from, to);
    };
    assert.throws(
      () => writeJsonAtomicSync(target, { state: "must-not-land" }, { attempts: 2, delayMs: 1 }),
      /replacement locked/
    );
    assert.deepEqual(JSON.parse(fs.readFileSync(target, "utf8")), { state: "must-survive" });

    fs.renameSync = originalRename;
    await Promise.all(Array.from({ length: 4 }, (_, worker) => runWorker(target, worker)));
    const final = JSON.parse(fs.readFileSync(target, "utf8"));
    assert(Number.isInteger(final.worker));
    assert(Number.isInteger(final.write));
    assert.equal(fs.readdirSync(directory).some((name) => name.endsWith(".tmp")), false);
  } finally {
    fs.renameSync = originalRename;
    fs.rmSync(directory, { recursive: true, force: true });
  }
  console.log("Safe atomic file verification passed: transient lock retry, rollback, stale cleanup, and concurrent writes.");
}

function runWorker(target, worker) {
  const helper = require.resolve("../src/services/safe-files");
  const source = `
    const { parentPort, workerData } = require("worker_threads");
    const { writeJsonAtomicSync } = require(workerData.helper);
    try {
      for (let write = 0; write < 12; write += 1) {
        writeJsonAtomicSync(workerData.target, { worker: workerData.worker, write });
      }
      parentPort.postMessage({ ok: true });
    } catch (error) {
      parentPort.postMessage({ ok: false, error: error.stack || error.message });
    }
  `;
  return new Promise((resolve, reject) => {
    const instance = new Worker(source, { eval: true, workerData: { helper, target, worker } });
    instance.once("message", (message) => message.ok ? resolve() : reject(new Error(message.error)));
    instance.once("error", reject);
  });
}

run().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});
