/**
 * The handshake between Tera's office packs and the room cloud-1 actually
 * measures.
 *
 * `GET /api/la-studio/tera/seats` was built so that a pack could be diffed
 * against the real room, seat id by seat id. Nothing has ever diffed against it.
 * A handshake nobody shakes is a comment, and this file is the difference: from
 * here on, every seat the upstream publishes is either **resolved by a shipped
 * pack** or **explicitly listed as unshipped, with a reason**. There is no third
 * state, which is what makes silent drift impossible — the day somebody authors
 * the pack, the list empties itself; the day the upstream adds a seat, this
 * fails and somebody has to decide what it is.
 *
 * ### Why all three are currently unshipped, and why that is the right answer
 *
 * The room is 3.9624 m square. Mateo Court is a 36 x 26 m courtyard block: 936 m²
 * against 15.7 m², sixty times the floor area, with a lobby, a press room and a
 * robotics lab that do not exist there. The two are not the same place and
 * cannot be made into each other, which is why this round twinned the two studio
 * *devices* — where the reading is measured and the placement is authored, and
 * the disclosure says which is which — and did not twin the room.
 *
 * Authoring the room itself is a separate decision, and it is the owner's rather
 * than an engineer's: `bed-01` is not a figure of speech. That is recorded here
 * rather than in a ticket, because this is the file somebody reads on the day
 * they decide to build it.
 */

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

/** Every pack this build ships, at full depth. */
const SHIPPED = [LUMBRIDGE_HQ, MATEO_COURT, FRONTIER_VALLEY].map(
  (pack) => new Plan(pack, { warn: false }),
);

/**
 * Seats the upstream publishes that no shipped pack resolves, and why.
 *
 * Every entry here is a promise that somebody looked at it. Deleting one means
 * a pack now carries that seat; adding one means a new seat appeared upstream
 * and somebody decided, on purpose, not to ship it yet.
 */
const UNSHIPPED: Readonly<Record<string, string>> = {
  "desk-01":
    "the LA Studio's own desk. No shipped pack is that room — Mateo Court is a " +
    "936 m² courtyard block and the studio is 15.7 m² — so binding this id to " +
    "one of its desks would put a measured address on an invented piece of " +
    "furniture.",
  "bed-01":
    "the room has a bed in it, and it is somebody's. Authoring a walkable, " +
    "publicly reachable twin of it is the owner's decision and has not been " +
    "made. Nothing here should make it by accident.",
  "floor-01":
    "the standing mark in the middle of the same room. Unshipped for the same " +
    "reason as the other two: the room is not authored.",
};

describe("the LA Studio seat handshake", () => {
  it("captured a body with the shape the upstream documents", () => {
    assert.equal(LA_STUDIO_SEATS.officeId, "la-studio");
    assert.ok(Number.isInteger(LA_STUDIO_SEATS.frameRev));
    assert.ok(LA_STUDIO_SEATS.seats.length > 0);
    // The slab is the strongest claim in the whole body and the reason a twin of
    // this room would be worth building: it was measured, not typed.
    assert.equal(LA_STUDIO_SEATS.slab.provenance, "measured");
    assert.ok(LA_STUDIO_SEATS.slab.widthM > 0 && LA_STUDIO_SEATS.slab.depthM > 0);
    assert.ok(!Number.isNaN(Date.parse(LA_STUDIO_SEATS.slab.measuredAt)));
    for (const seat of LA_STUDIO_SEATS.seats) {
      assert.ok(seat.id.length > 0);
      assert.ok(Number.isFinite(seat.position.x) && Number.isFinite(seat.position.z));
      assert.ok(seat.position.x >= 0 && seat.position.x <= LA_STUDIO_SEATS.slab.widthM, seat.id);
      assert.ok(seat.position.z >= 0 && seat.position.z <= LA_STUDIO_SEATS.slab.depthM, seat.id);
      assert.ok(seat.pose === "sit" || seat.pose === "stand", seat.id);
    }
  });

  it("carries no coordinate, no address and nothing home-relative", () => {
    // The upstream store this room belongs to is centred on somebody's home, and
    // several of its columns invert to a distance from it. None of them is on
    // this endpoint and none may ever be captured into this repository.
    const text = JSON.stringify(LA_STUDIO_SEATS);
    for (const forbidden of [
      "lat", "lng", "longitude", "latitude", "bearing", "distanceKm", "distance_km",
      "threat", "address", "street",
    ]) {
      assert.ok(!text.includes(forbidden), `the seat fixture carries "${forbidden}"`);
    }
  });

  it("accounts for every upstream seat: shipped, or listed as unshipped", () => {
    for (const seat of LA_STUDIO_SEATS.seats) {
      const resolved = SHIPPED.some((plan) => plan.seat(seat.id) !== null);
      const excused = Object.prototype.hasOwnProperty.call(UNSHIPPED, seat.id);
      assert.ok(
        resolved || excused,
        `upstream publishes seat "${seat.id}" and no shipped pack resolves it, and ` +
          "nothing in UNSHIPPED says why. Author it, or write down the reason.",
      );
      assert.ok(
        !(resolved && excused),
        `seat "${seat.id}" is both shipped and listed as unshipped — delete the ` +
          "UNSHIPPED entry, it is now a lie.",
      );
    }
  });

  it("keeps the unshipped list honest in both directions", () => {
    const published = new Set(LA_STUDIO_SEATS.seats.map((seat) => seat.id));
    for (const [id, reason] of Object.entries(UNSHIPPED)) {
      assert.ok(
        published.has(id),
        `UNSHIPPED excuses "${id}", which the upstream no longer publishes`,
      );
      // A reason, not a placeholder. This is the field that stops the list
      // becoming a way of silencing the check.
      assert.ok(reason.length > 40, `UNSHIPPED["${id}"] does not say anything`);
    }
  });

  it("does not let a shipped pack quietly reuse an upstream seat id", () => {
    // The inverse drift: a pack author picks `desk-01` for a desk in Mateo Court
    // and, the day a presence feed is wired up, the LA Studio's occupants appear
    // in a fictional lobby. Seat ids are what `Presence` binds on.
    for (const plan of SHIPPED) {
      for (const seat of LA_STUDIO_SEATS.seats) {
        const collision = plan.seat(seat.id);
        assert.ok(
          collision === null,
          `${plan.office.id} declares seat "${seat.id}", which is an LA Studio id`,
        );
      }
    }
  });
});
