/**
 * The two places a flight's riser count is decided, pinned to each other.
 *
 * `src/interiors/shell.ts` divides a climbing leg into whole 178 mm risers and
 * lays a tread on each; `src/engine/officeMinimap.ts` draws one tick per riser
 * on the floor plan. Neither imports the other — the minimap builds no meshes
 * and has no business importing the file that does, and the shell has no
 * business knowing a widget exists — so the constant is stated twice.
 *
 * A constant stated twice is a constant that drifts, and the drift here is
 * quiet: a plan showing eleven ticks on a flight of fourteen looks fine. So the
 * two are read out of the source and compared, which is the cheapest thing that
 * actually catches it. Reading source text rather than exporting the constants
 * is deliberate: neither is part of either module's interface, and widening an
 * interface to make a test easier is how a private number becomes an API.
 */

import assert from "node:assert/strict";
import { readFileSync } from "node:fs";
import { describe, it } from "node:test";

function constantIn(path: string, name: string): number {
  const source = readFileSync(new URL(path, import.meta.url), "utf8");
  const match = new RegExp(`const ${name} = ([0-9.]+);`).exec(source);
  assert.ok(match, `${name} is not declared in ${path}`);
  const value = Number(match[1]);
  assert.ok(Number.isFinite(value) && value > 0, `${name} is ${match[1]}`);
  return value;
}

describe("a drawn flight and a drawn plan agree about how many risers it has", () => {
  it("uses one riser height in the shell and in the minimap", () => {
    const shell = constantIn("../../interiors/shell.ts", "TARGET_RISER_M");
    const minimap = constantIn("../../engine/officeMinimap.ts", "MINIMAP_RISER_M");
    assert.equal(minimap, shell);
  });

  it("keeps that height inside what a person can climb", () => {
    const riser = constantIn("../../interiors/shell.ts", "TARGET_RISER_M");
    // Commercial stairs run about 150-190 mm. Outside that a flight stops
    // reading as a flight: too shallow and it is a ramp with lines on it, too
    // steep and the actor's feet visibly miss the treads.
    assert.ok(riser >= 0.15 && riser <= 0.19, `${riser} m`);
  });
});
