import { describe, it, beforeEach } from "node:test";
import assert from "node:assert/strict";
import { RelayQueue, isRole } from "./queue.ts";

describe("RelayQueue", () => {
  let q: RelayQueue;

  beforeEach(() => {
    q = new RelayQueue();
  });

  it("post + read roundtrip returns the message with correct fields", () => {
    q.post("dev-b", "pm", "status", "Task P4 DONE");
    const msgs = q.read("pm");
    assert.equal(msgs.length, 1);
    assert.equal(msgs[0].from, "dev-b");
    assert.equal(msgs[0].to, "pm");
    assert.equal(msgs[0].kind, "status");
    assert.equal(msgs[0].body, "Task P4 DONE");
    assert.ok(typeof msgs[0].id === "string" && msgs[0].id.length > 0);
    assert.ok(typeof msgs[0].ts === "string");
  });

  it("consume-once: second read returns empty", () => {
    q.post("dev-a", "pm", "question", "Should I use approach A?");
    q.read("pm");
    const second = q.read("pm");
    assert.deepEqual(second, []);
  });

  it("list_pending does not drain inbox", () => {
    q.post("dev-b", "pm", "directive", "PROCEED");
    const before = q.pending("pm");
    assert.equal(before.count, 1);
    const after = q.read("pm");
    assert.equal(after.length, 1);
  });

  it("FIFO ordering across multiple senders", () => {
    q.post("dev-a", "pm", "status", "first");
    q.post("dev-b", "pm", "status", "second");
    q.post("dev-a", "pm", "question", "third");
    const msgs = q.read("pm");
    assert.equal(msgs.length, 3);
    assert.equal(msgs[0].body, "first");
    assert.equal(msgs[1].body, "second");
    assert.equal(msgs[2].body, "third");
  });

  it("isRole rejects unknown strings", () => {
    assert.ok(isRole("pm"));
    assert.ok(isRole("dev-a"));
    assert.ok(isRole("dev-b"));
    assert.ok(isRole("dev-c"));
    assert.ok(isRole("dev-d"));
    assert.ok(isRole("dev-e"));
    assert.ok(isRole("dev-f"));
    assert.ok(!isRole("dev-g"));
    assert.ok(!isRole(""));
    assert.ok(!isRole("PM"));
  });
});
