import assert from "node:assert/strict";
import { unlink } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { randomUUID } from "node:crypto";
import test from "node:test";
import { FailureStore } from "./failure-store.js";

test("failure backoff is durable and can be cleared", async () => {
  const path = join(tmpdir(), `sharepoint-failures-${randomUUID()}.json`);
  try {
    const first = new FailureStore(path);
    await first.load();
    assert.equal(first.canRun("Attachment:00P1"), true);
    await first.recordFailure("Attachment:00P1", "temporary", true);
    assert.equal(first.canRun("Attachment:00P1"), false);

    const restored = new FailureStore(path);
    await restored.load();
    assert.equal(restored.canRun("Attachment:00P1"), false);
    await restored.clear("Attachment:00P1");
    assert.equal(restored.canRun("Attachment:00P1"), true);
  } finally {
    await unlink(path).catch(() => undefined);
  }
});

test("concurrent updates are serialized without losing failure state", async () => {
  const path = join(tmpdir(), `sharepoint-failures-${randomUUID()}.json`);
  try {
    const store = new FailureStore(path);
    await store.load();
    await Promise.all(
      Array.from({ length: 20 }, (_, index) =>
        store.recordFailure(`ContentVersion:068${index}`, "metadata failure", false),
      ),
    );

    const restored = new FailureStore(path);
    await restored.load();
    for (let index = 0; index < 20; index += 1) {
      assert.equal(restored.canRun(`ContentVersion:068${index}`), false);
    }
  } finally {
    await unlink(path).catch(() => undefined);
  }
});
