// AereDelegationRegistry tests.

const { expect } = require("chai");
const { ethers } = require("hardhat");

describe("AereDelegationRegistry", function () {
  async function deploy() {
    const [deployer, alice, bob, indexer] = await ethers.getSigners();
    const R = await ethers.getContractFactory("AereDelegationRegistry");
    const r = await R.deploy();
    await r.waitForDeployment();
    return { deployer, alice, bob, indexer, r };
  }

  it("permissionless register + reverts on double-register", async function () {
    const { alice, r } = await deploy();
    await expect(r.connect(alice).register()).to.emit(r, "Registered");
    expect(await r.isRegistered(alice.address)).to.equal(true);
    expect(await r.registeredCount()).to.equal(1n);
    await expect(r.connect(alice).register())
      .to.be.revertedWithCustomError(r, "AlreadyRegistered");
  });

  it("unregister removes from list + adjusts indices", async function () {
    const { alice, bob, r } = await deploy();
    await r.connect(alice).register();
    await r.connect(bob).register();
    expect(await r.registeredCount()).to.equal(2n);
    await r.connect(alice).unregister();
    expect(await r.isRegistered(alice.address)).to.equal(false);
    expect(await r.registeredCount()).to.equal(1n);
    // Bob still in.
    expect(await r.isRegistered(bob.address)).to.equal(true);
  });

  it("notifyNonce updates lastSeen + only if higher", async function () {
    const { alice, indexer, r } = await deploy();
    await r.connect(alice).register();
    await expect(r.connect(indexer).notifyNonce(alice.address, 5))
      .to.emit(r, "NonceSeen");
    const e1 = await r.entries(alice.address);
    expect(e1.lastSeenNonce).to.equal(5n);
    // Lower nonce: no update, no event.
    await r.connect(indexer).notifyNonce(alice.address, 3);
    const e2 = await r.entries(alice.address);
    expect(e2.lastSeenNonce).to.equal(5n);
  });

  it("notifyNonce on unregistered reverts", async function () {
    const { alice, indexer, r } = await deploy();
    await expect(r.connect(indexer).notifyNonce(alice.address, 1))
      .to.be.revertedWithCustomError(r, "NotRegistered");
  });

  it("page returns slice of registered list", async function () {
    const env = await deploy();
    const { r } = env;
    const signers = await ethers.getSigners();
    // Register 5 accounts.
    for (let i = 0; i < 5; i++) {
      await r.connect(signers[i]).register();
    }
    const first = await r.page(0, 3);
    expect(first.length).to.equal(3);
    expect(first[0]).to.equal(signers[0].address);
    const last = await r.page(3, 10);
    expect(last.length).to.equal(2);
  });
});
