/**
 * The reference pack, against the checklist its own README ends with.
 *
 * `src/offices/README.md` closes with six things to check before calling a pack
 * done, and until this file existed the pack those instructions are written
 * about had none of them checked. That was survivable while it was one storey
 * and fifteen rooms authored in one sitting. It stopped being survivable when a
 * second level and a wing arrived, because the failure mode of a floorplan is
 * not a crash — `Plan` never throws — it is a room nobody can get into, which
 * renders perfectly and looks completely fine from every camera angle.
 *
 * Two of the checks here are worth their weight on their own:
 *
 *   - **Reachability.** Item 2 on the list, and the one that cannot be eyeballed:
 *     a door authored 200 mm past the end of its wall is silently dropped, the
 *     room behind it is sealed, and the only evidence is a line in
 *     `plan.problems` that nothing reads. That exact bug happened once while the
 *     wing was being written.
 *   - **The balustrade.** The gallery is 16.8 m above terrazzo. `Plan` derives
 *     the walk collider from the wall list, so the difference between a
 *     balustrade and a decorative rail is whether it is in that list — and both
 *     look identical in a screenshot.
 */

import assert from "node:assert/strict";
import { describe, it } from "node:test";
import { Plan } from "../interiors/plan.ts";
import LUMBRIDGE_HQ from "../offices/lumbridge-hq.ts";
import FRONTIER_VALLEY from "../offices/frontier-valley.ts";
import MATEO_COURT from "../offices/mateo-court.ts";
import { OFFICE_SITES } from "../offices/sites.ts";

const plan = new Plan(LUMBRIDGE_HQ, { warn: false });

/**
 * Which rooms on a level can be walked to from a point, at 0.1 m.
 *
 * Shared by all three packs, because it was written three times otherwise and
 * the third copy is where a subtle divergence lives. The grid is finer than it
 * looks like it needs to be and that is not optional: `blocked` inflates by the
 * walker's radius, so threading a 0.9 m door with a 0.3 m radius leaves 0.3 m of
 * clear width, and a 0.25 m grid can straddle that and report a sealed room that
 * is fine. Erring the other way is not possible — a coarser grid only ever
 * reaches fewer rooms, so a pass is always a real pass.
 */
function reachableRoomsOf(
  plan: Plan,
  levelId: string,
  entry: { x: number; z: number },
): Set<string> {
  const STEP = 0.1;
  const RADIUS = 0.3;
  const b = plan.bounds;
  const cols = Math.ceil(b.width / STEP);
  const rows = Math.ceil(b.depth / STEP);
  const at = (c: number, r: number) => ({ x: b.minX + c * STEP, z: b.minZ + r * STEP });

  const room: (string | null)[] = new Array(cols * rows).fill(null);
  for (let r = 0; r < rows; r += 1) {
    for (let c = 0; c < cols; c += 1) {
      room[r * cols + c] = plan.roomAt(levelId, at(c, r))?.id ?? null;
    }
  }

  const sc = Math.round((entry.x - b.minX) / STEP);
  const sr = Math.round((entry.z - b.minZ) / STEP);
  assert.ok(room[sr * cols + sc], `${levelId}'s entry point is not inside a room`);

  const seen = new Uint8Array(cols * rows);
  const queue: [number, number][] = [[sc, sr]];
  seen[sr * cols + sc] = 1;
  while (queue.length > 0) {
    const [c, r] = queue.pop() as [number, number];
    for (const [dc, dr] of [
      [1, 0],
      [-1, 0],
      [0, 1],
      [0, -1],
    ]) {
      const nc = c + (dc as number);
      const nr = r + (dr as number);
      if (nc < 0 || nr < 0 || nc >= cols || nr >= rows) continue;
      const i = nr * cols + nc;
      if (seen[i] === 1 || room[i] === null) continue;
      if (plan.blocked(levelId, at(c, r), at(nc, nr), RADIUS)) continue;
      seen[i] = 1;
      queue.push([nc, nr]);
    }
  }

  const reached = new Set<string>();
  for (let i = 0; i < seen.length; i += 1) {
    const id = room[i];
    if (seen[i] === 1 && id != null) reached.add(id);
  }
  return reached;
}



describe("the reference pack resolves cleanly", () => {
  /** Checklist item 1, and the one everything else here depends on. */
  it("reports no problems at all", () => {
    assert.deepEqual(
      plan.problems.map((p) => `${p.where}: ${p.message} (${p.action})`),
      [],
    );
  });

  /**
   * One storey, and the shape of the room that is most of it.
   *
   * The comment that stood here argued about a `PLENUM` constant and a level 2,
   * and this pack has had neither since it became a twelve-by-nine studio. A
   * stale comment on a passing test is worse than no comment at all, because it
   * is what the next author reads to find out what the pack *is* — and it sent
   * them looking for two storeys in a flat.
   *
   * The floor-to-floor argument it was making is still worth making, and it is
   * now made where there are two storeys to make it about: `the Mateo Court
   * pack` below asserts that level 2 lands on floor-to-*floor* and not on the
   * ceiling height, which is the classic way to bury one slab inside the one
   * below it.
   *
   * What is asserted here is the studio itself: one level at y = 0, and a
   * live/work room that is the whole plate inside the façade.
   */
  it("is an honest twelve-by-nine metre single-level studio", () => {
    assert.deepEqual(plan.levels.map((level) => [level.id, level.floorY]), [["level-1", 0]]);
    assert.deepEqual(LUMBRIDGE_HQ.levels[0]?.floorplan.rooms[3]?.outline, [
      { x: 0.2, z: 3.15 },
      { x: 0.2, z: 8.8 },
      { x: 11.8, z: 8.8 },
      { x: 11.8, z: 3.15 },
    ]);
  });

  it("keeps every viewpoint on a level that exists", () => {
    // `Plan` drops a viewpoint whose level does not resolve, so this is really
    // an assertion that none were dropped — which the count makes visible in a
    // way `problems` being empty already implies but does not state.
    assert.equal(plan.viewpoints.length, 5);
    const levels = new Set(plan.levels.map((l) => l.id));
    for (const v of plan.viewpoints) assert.ok(levels.has(v.levelId), `${v.id} is on nothing`);
  });
});

describe("seat ids", () => {
  const seats = plan.allSeats();

  /**
   * The one property the README asks for in capitals, because a `Presence` binds
   * to a seat id and ids are unique **per kind and building-wide**, not per
   * level. Two storeys is exactly when somebody reuses a prefix.
   */
  it("are unique across the whole building, not merely per storey", () => {
    const ids = seats.map((s) => s.id);
    assert.equal(new Set(ids).size, ids.length);
  });

  /**
   * Not a count for its own sake. `DeskBank` expansion is contractual — stations
   * numbered from 1 along each row and then down the rows, zero-padded to two —
   * and a bank that silently expanded to the wrong size would change every id
   * after it.
   */
  it("expand the desk banks to the documented ids", () => {
    const ids = new Set(seats.map((s) => s.id));
    assert.equal(seats.length, 5);
    for (const id of ["sf-agent-01", "sf-agent-02", "sf-island-01", "sf-island-02", "sf-lounge-01"]) {
      assert.ok(ids.has(id), `${id} is missing`);
    }
  });
});

/**
 * Checklist item 2: every room you can walk into can actually be walked into.
 *
 * A flood fill rather than a spot check, because a spot check finds the door you
 * remembered to look at. The grid is 0.1 m, which is finer than it looks like it
 * needs to be and is not optional: `blocked` inflates by the walker's radius, so
 * threading a 0.9 m door with a 0.3 m radius leaves 0.3 m of clear width, and a
 * 0.25 m grid can straddle that and report a sealed room that is fine. Getting
 * that wrong the other way — a coarse grid that "passes" — is not possible here,
 * since a coarser grid only ever reaches fewer rooms.
 */
describe("every room is reachable on foot", () => {
  const STEP = 0.1;
  const RADIUS = 0.3;

  /** Where somebody arrives: the entrance downstairs, the landing upstairs. */
  const ENTRY: Record<string, { x: number; z: number }> = {
    "level-1": { x: 1.02, z: 7.68 },
  };

  function reachableRooms(levelId: string): Set<string> {
    const b = plan.bounds;
    const cols = Math.ceil(b.width / STEP);
    const rows = Math.ceil(b.depth / STEP);
    const at = (c: number, r: number) => ({ x: b.minX + c * STEP, z: b.minZ + r * STEP });

    const room: (string | null)[] = new Array(cols * rows).fill(null);
    for (let r = 0; r < rows; r += 1) {
      for (let c = 0; c < cols; c += 1) {
        room[r * cols + c] = plan.roomAt(levelId, at(c, r))?.id ?? null;
      }
    }

    const entry = ENTRY[levelId];
    assert.ok(entry, `no entry point declared for ${levelId}`);
    const sc = Math.round((entry.x - b.minX) / STEP);
    const sr = Math.round((entry.z - b.minZ) / STEP);
    assert.ok(room[sr * cols + sc], `${levelId}'s entry point is not inside a room`);

    const seen = new Uint8Array(cols * rows);
    const queue: [number, number][] = [[sc, sr]];
    seen[sr * cols + sc] = 1;
    while (queue.length > 0) {
      const [c, r] = queue.pop() as [number, number];
      for (const [dc, dr] of [
        [1, 0],
        [-1, 0],
        [0, 1],
        [0, -1],
      ]) {
        const nc = c + (dc as number);
        const nr = r + (dr as number);
        if (nc < 0 || nr < 0 || nc >= cols || nr >= rows) continue;
        const i = nr * cols + nc;
        if (seen[i] === 1 || room[i] === null) continue;
        if (plan.blocked(levelId, at(c, r), at(nc, nr), RADIUS)) continue;
        seen[i] = 1;
        queue.push([nc, nr]);
      }
    }

    const reached = new Set<string>();
    for (let i = 0; i < seen.length; i += 1) {
      // `!= null` rather than `!== null`: indexing a `(string | null)[]` under
      // `noUncheckedIndexedAccess` widens to include `undefined` too.
      const id = room[i];
      if (seen[i] === 1 && id != null) reached.add(id);
    }
    return reached;
  }

  for (const level of plan.levels) {
    it(`${level.id}: from the way in, without passing through a wall`, () => {
      const reached = reachableRooms(level.id);
      const sealed = level.rooms.map((r) => r.id).filter((id) => !reached.has(id));
      assert.deepEqual(sealed, [], `sealed rooms on ${level.id}`);
    });
  }
});

/**
 * The gallery is a balcony over a double-height room, and the drop is a storey.
 *
 * `Plan.blocked` is the collider a walk controller is told to use, so this is
 * the only place the difference between a balustrade and a handrail-shaped prop
 * is observable. A prop would leave the edge open and nothing would look wrong.
 */
describe("the studio arrival", () => {
  it("starts inside the live/work room with collision-clear movement", () => {
    const arrival = LUMBRIDGE_HQ.viewpoints[0]?.focus.at;
    assert.ok(arrival);
    assert.equal(plan.roomAt("level-1", arrival)?.id, "live-work");
    assert.equal(plan.blocked("level-1", arrival, { x: arrival.x + 0.6, z: arrival.z }, 0.3), false);
  });

  /**
   * And the way *on* is still open, which is the other half of the same claim: a
   * balcony you cannot fall off and also cannot reach is a balcony nobody has
   * noticed is broken.
   */
  it("keeps all five authored views meaningful and distinct", () => {
    assert.deepEqual(
      LUMBRIDGE_HQ.viewpoints.map((view) => view.id),
      ["arrival", "studio", "agent-bench", "demo-lounge", "kitchen-home"],
    );
  });
});

/**
 * The commons is the reason the wing exists, and "double height" is a property
 * of the walls rather than of the room. A `Room` carries `ceiling: null` and a
 * `Wall` carries a height; get the second wrong and the void has a lid at 2.8 m
 * that you cannot see but the light rig can.
 */
describe("the studio programme", () => {
  it("names every promised live/work zone without pretending it is a tower floor", () => {
    const level1 = plan.levels.find((l) => l.id === "level-1");
    assert.deepEqual(
      level1?.rooms.map((room) => room.name),
      ["Kitchen", "Sleeping Alcove", "Bath / Storage", "Live / Work Studio"],
    );
  });

  it("uses the complete original habitat kit", () => {
    const kinds = new Set((LUMBRIDGE_HQ.levels[0]?.floorplan.props ?? []).map((prop) => prop.kind));
    for (const id of [
      "tera:bed.platform",
      "tera:sofa.modular",
      "tera:kitchen.run",
      "tera:kitchen.island",
      "tera:storage.wardrobe",
      "tera:seat.stool",
      "tera:light.floor",
    ]) assert.ok(kinds.has(id), `${id} is not placed in SF HQ`);
  });
});

/**
 * The second pack, held to the same bar as the first.
 *
 * A shipped pack that nothing asserts on is a pack that quietly stops resolving
 * the first time somebody edits a shared constant. It gets the two checks that
 * catch that — clean resolution and a walkable building — plus the one thing
 * that is specific to it: it is a *hangar*, and the point of shipping it is that
 * the format describes one room fifty-four metres across as readily as it
 * describes a corridor with fifteen doors off it.
 */
describe("the Frontier Valley pack", () => {
  const fv = new Plan(FRONTIER_VALLEY, { warn: false });

  it("resolves with no problems", () => {
    assert.deepEqual(
      fv.problems.map((p) => `${p.where}: ${p.message} (${p.action})`),
      [],
    );
  });

  /**
   * The deck is a level, and that is the fix for a real defect rather than a
   * modelling preference: authored as a `Room` it had no floor height, so its
   * slab lay on the concrete while its furniture floated 4.4 m over it.
   */
  it("puts the mezzanine on its own level, at deck height", () => {
    assert.deepEqual(
      fv.levels.map((l) => [l.id, l.floorY]),
      [
        ["level-1", 0],
        ["level-mezz", 4.4],
      ],
    );
  });

  it("has unique seat ids, which must not collide with the other pack's", () => {
    const mine = fv.allSeats().map((s) => s.id);
    assert.equal(new Set(mine).size, mine.length);
    // Not a hard requirement of the format — ids are unique per *building* — but
    // a deployment serving both from one presence API would find out the hard
    // way, and the two packs cost nothing by staying disjoint.
    const theirs = new Set(plan.allSeats().map((s) => s.id));
    const shared = mine.filter((id) => theirs.has(id));
    assert.deepEqual(shared, [], "seat ids shared between the two shipped packs");
  });

  it("can be walked from the personnel door to every room", () => {
    const STEP = 0.1;
    const RADIUS = 0.3;
    const b = fv.bounds;
    const cols = Math.ceil(b.width / STEP);
    const rows = Math.ceil(b.depth / STEP);
    const at = (c: number, r: number) => ({ x: b.minX + c * STEP, z: b.minZ + r * STEP });

    const room: (string | null)[] = new Array(cols * rows).fill(null);
    for (let r = 0; r < rows; r += 1) {
      for (let c = 0; c < cols; c += 1) {
        room[r * cols + c] = fv.roomAt("level-1", at(c, r))?.id ?? null;
      }
    }

    // Just inside the west gable's personnel door.
    const sc = Math.round((1.0 - b.minX) / STEP);
    const sr = Math.round((14.4 - b.minZ) / STEP);
    assert.ok(room[sr * cols + sc], "the way in is not inside a room");

    const seen = new Uint8Array(cols * rows);
    const queue: [number, number][] = [[sc, sr]];
    seen[sr * cols + sc] = 1;
    while (queue.length > 0) {
      const [c, r] = queue.pop() as [number, number];
      for (const [dc, dr] of [[1, 0], [-1, 0], [0, 1], [0, -1]]) {
        const nc = c + (dc as number);
        const nr = r + (dr as number);
        if (nc < 0 || nr < 0 || nc >= cols || nr >= rows) continue;
        const i = nr * cols + nc;
        if (seen[i] === 1 || room[i] === null) continue;
        if (fv.blocked("level-1", at(c, r), at(nc, nr), RADIUS)) continue;
        seen[i] = 1;
        queue.push([nc, nr]);
      }
    }

    const reached = new Set<string>();
    for (let i = 0; i < seen.length; i += 1) {
      const id = room[i];
      if (seen[i] === 1 && id != null) reached.add(id);
    }
    // Level 1 only. The mezzanine is a level of its own now and is reached by a
    // stair this pack does not model, so a flood fill across the slab cannot and
    // should not walk onto it.
    const sealed = fv.levels[0]!.rooms.map((r) => r.id).filter((id) => !reached.has(id));
    assert.deepEqual(sealed, [], "sealed rooms in the hangar");
  });

  it("guards the mezzanine edge, which is a 4.4 m drop onto concrete", () => {
    // On the deck's own level — the balustrade belongs to it, not to the slab
    // below, which is the whole point of the deck being a level.
    assert.ok(fv.blocked("level-mezz", { x: 39.0, z: 25.0 }, { x: 37.0, z: 25.0 }, 0.3));
    assert.ok(fv.blocked("level-mezz", { x: 45.0, z: 21.0 }, { x: 45.0, z: 19.0 }, 0.3));
  });

  /**
   * And the deck is genuinely up there. `Plan` resolves a seat's `y` from its
   * level's floor, so this is the assertion that would have caught the original
   * defect: authored as a ground-floor room, every one of these was at y = 0
   * with a chair drawn 4.4 m above it.
   */
  it("stands its occupants on the deck rather than on the concrete", () => {
    for (const id of ["mezz-01", "mezz-02", "mezz-03"]) {
      assert.equal(fv.seat(id)?.y, 4.4, `${id} is not on the deck`);
    }
  });
});

/**
 * All shipped packs declare where they stand, and the three are deliberately
 * nothing alike — which is the entire argument for the field existing.
 */
describe("the sites", () => {
  const packs = [LUMBRIDGE_HQ, FRONTIER_VALLEY, MATEO_COURT];

  it("are all declared", () => {
    for (const pack of packs) assert.ok(pack.site, `${pack.name} has no site`);
  });

  it("put one high in the air and one on the ground", () => {
    assert.ok(
      (LUMBRIDGE_HQ.site?.elevation ?? 0) > 100,
      "the tower office should be a long way up",
    );
    assert.ok(
      (FRONTIER_VALLEY.site?.elevation ?? 999) < 20,
      "the hangar should be near the ground",
    );
  });

  it("carry headings inside the compass", () => {
    for (const pack of packs) {
      const h = pack.site?.heading ?? 0;
      assert.ok(h >= 0 && h < 360, `${pack.id} has a heading of ${h}`);
    }
  });

  it("puts the Bay Area offices on the board the city view draws", () => {
    // Not a format requirement — an office may stand anywhere — but these two
    // are meant to be places in *this* product's San Francisco, and a
    // coordinate typo that put one in Nevada would otherwise render fine.
    for (const pack of [LUMBRIDGE_HQ, FRONTIER_VALLEY]) {
      const site = pack.site;
      assert.ok(site);
      assert.ok(site.lat > 37.2 && site.lat < 38.2, `${pack.id} latitude ${site.lat}`);
      assert.ok(site.lng > -122.8 && site.lng < -121.8, `${pack.id} longitude ${site.lng}`);
    }
  });

  it("gives every map destination a finite, aligned exterior glyph", () => {
    for (const pack of packs) {
      const site = pack.site;
      assert.ok(site, `${pack.id} has no site`);
      const exterior = site.exterior;
      assert.ok(exterior, `${pack.id} has no exterior glyph`);
      assert.equal(exterior.kind, "building");
      assert.equal(exterior.heading, site.heading, `${pack.id} exterior faces away from its plan`);
      for (const [field, value] of Object.entries({
        width: exterior.width,
        depth: exterior.depth,
        height: exterior.height,
        storeys: exterior.storeys,
      })) {
        assert.ok(Number.isFinite(value) && value > 0, `${pack.id} has invalid ${field}: ${value}`);
      }
    }
  });
});

/**
 * `offices/sites.ts` and the packs must not drift.
 *
 * The city draws its doors from `OFFICE_SITES` because a pack is a lazy chunk
 * and the board wants the pins before anybody opens one. That means two places
 * name the same building, and nothing in the type system ties them together —
 * a coordinate edited in the pack and not in the table would put the marker on
 * one building and the sun on another, and both would look entirely plausible.
 */
describe("the office site table", () => {
  it("lists exactly the packs this build ships", () => {
    assert.deepEqual(
      OFFICE_SITES.map((e) => e.id).sort(),
      [FRONTIER_VALLEY.id, LUMBRIDGE_HQ.id, MATEO_COURT.id].sort(),
    );
  });

  it("hands each pack the very same site object it publishes", () => {
    for (const pack of [LUMBRIDGE_HQ, FRONTIER_VALLEY, MATEO_COURT]) {
      const entry = OFFICE_SITES.find((e) => e.id === pack.id);
      assert.ok(entry, `${pack.id} is missing from OFFICE_SITES`);
      // Identity, not equality: the packs import from the table, so anything
      // less than the same reference means somebody has restated a coordinate.
      assert.equal(entry.site, pack.site, `${pack.id} has a site of its own`);
    }
  });

  it("publishes truthful environment names and runtime status", () => {
    assert.deepEqual(
      OFFICE_SITES.map(({ id, name, status }) => ({ id, name, status })),
      [
        { id: "lumbridge-hq", name: "SF HQ · Studio", status: "active" },
        { id: "frontier-valley", name: "Frontier Valley", status: "building" },
        { id: "mateo-court", name: "LA HQ · Office", status: "active" },
      ],
    );
  });
});

/**
 * The third pack, and the first on the other board.
 *
 * A courtyard block: a ring of rooms round an open-air yard with **no corridor
 * anywhere** — every door opens onto the yard, and the yard does the job a
 * corridor does in the other two. That makes it the first pack whose
 * circulation is outdoors, and the first whose `ceiling: null` means there is
 * genuinely no ceiling rather than "take the lid off so the shot can see in".
 */
describe("the Mateo Court pack", () => {
  const mc = new Plan(MATEO_COURT, { warn: false });

  it("resolves with no problems", () => {
    assert.deepEqual(
      mc.problems.map((p) => `${p.where}: ${p.message} (${p.action})`),
      [],
    );
  });

  it("stacks its upper floor floor-to-floor", () => {
    assert.deepEqual(
      mc.levels.map((l) => [l.id, l.floorY]),
      [
        ["level-1", 0],
        ["level-2", 5],
      ],
    );
  });

  it("keeps its seat ids disjoint from both other packs", () => {
    const mine = mc.allSeats().map((s) => s.id);
    assert.equal(new Set(mine).size, mine.length);
    const others = new Set([
      ...plan.allSeats().map((s) => s.id),
      ...new Plan(FRONTIER_VALLEY, { warn: false }).allSeats().map((s) => s.id),
    ]);
    assert.deepEqual(mine.filter((id) => others.has(id)), []);
  });

  /**
   * Thirty-four addresses, from four benches and ten places written by hand.
   *
   * This used to read twenty-four and to assert that `works-b` did **not**
   * exist, on the argument that capacity is a plan decision and a floor filled
   * edge to edge with generated workstations is a call centre. The argument
   * still holds; the plan decision changed. A 260 m² agent floor now has two
   * benches with a screened gap between them (12 + 4) and the 158 m² model loft
   * has two (2 + 6), which is a floor with bays rather than a floor with a
   * horizon. What the assertion is really for is unchanged: it is the thing that
   * notices a bank quietly growing a column, because `columns` and `rows` are
   * two characters each and every one of them mints a public address.
   */
  it("holds the authored office at thirty-four seat addresses", () => {
    const ids = mc.allSeats().map((seat) => seat.id);
    assert.equal(ids.length, 34);
    for (const id of [
      "works-a-01",
      "works-a-12",
      "works-b-01",
      "works-b-04",
      "loft-a-01",
      "loft-b-06",
      "review-04",
      "loggia-01",
    ]) {
      assert.ok(ids.includes(id), `${id} is missing`);
    }
    // Nothing past the two banks on each floor. `works-c` is the id somebody
    // adds when they want ten more desks and have not read the paragraph above.
    assert.equal(ids.some((id) => id.startsWith("works-c-")), false);
    assert.equal(ids.some((id) => id.startsWith("loft-c-")), false);
  });

  /**
   * **The check that matters most in this pack.**
   *
   * Every door through the 0.25 m courtyard skin is 1.2 m rather than the 0.9 m
   * the rest of the library uses, and that is not a style choice: `blocked`
   * inflates by the walker's radius *and* by the wall's thickness, so a 0.9 m
   * leaf in a wall this thick leaves too little clear width and seals the room
   * behind it — while rendering perfectly. Two rooms were sealed exactly that
   * way on the pack's first pass. A well-meaning edit back to 0.9 for
   * consistency would do it again, and this is the only thing that would say so.
   */
  for (const [levelId, entry] of [
    ["level-1", { x: 18.1, z: 1.0 }],
    ["level-2", { x: 8.4, z: 10.4 }],
  ] as const) {
    it(`${levelId}: every room reachable from the way in`, () => {
      const reached = reachableRoomsOf(mc, levelId, entry);
      const sealed = mc.levels
        .find((l) => l.id === levelId)!
        .rooms.map((r) => r.id)
        .filter((id) => !reached.has(id));
      assert.deepEqual(sealed, [], `sealed rooms on ${levelId}`);
    });
  }

  /**
   * The loggia rail, and the gap in it.
   *
   * Both halves matter and only together: a rail that also sealed the stair head
   * would pass an assertion that only checked you cannot fall off.
   */
  it("guards the loggia edge without sealing the way up", () => {
    assert.ok(mc.blocked("level-2", { x: 8.8, z: 9.0 }, { x: 10.6, z: 9.0 }, 0.3));
    assert.ok(mc.blocked("level-2", { x: 8.8, z: 14.0 }, { x: 10.6, z: 14.0 }, 0.3));
    assert.ok(mc.blocked("level-2", { x: 18.0, z: 7.6 }, { x: 18.0, z: 9.4 }, 0.3));
    assert.ok(
      !mc.blocked("level-2", { x: 8.8, z: 10.4 }, { x: 10.4, z: 10.4 }, 0.3),
      "the stair head is walled off",
    );
  });

  it("stands its upper-floor occupants on the deck", () => {
    for (const id of ["loggia-01", "loft-a-01"]) {
      assert.equal(mc.seat(id)?.y, 5, `${id} is not on the deck`);
    }
  });

  it("leaves the yard open to the sky", () => {
    const court = mc.levels[0]?.rooms.find((r) => r.id === "court");
    assert.ok(court, "no courtyard");
    assert.equal(court.ceiling, null);
  });

  /** The point of the pack: the Southland board finally has a door. */
  it("stands on the Southland board", () => {
    const site = MATEO_COURT.site;
    assert.ok(site);
    assert.ok(site.lat > 33.28 && site.lat < 34.36, `latitude ${site.lat}`);
    assert.ok(site.lng > -118.88 && site.lng < -117.22, `longitude ${site.lng}`);
  });
});
