/**
 * When a board loads before anybody asks for it.
 *
 * ## What this is for
 *
 * "One map" is a claim about continuity, and continuity is paid for by having
 * the detail already in memory when the camera arrives. CONTRACT §1.1 already
 * keeps three boards resident on a desktop and pins California; what was missing
 * was anything that *fills* that residency before a visitor demands it. This is
 * the policy half of that — the half with no DOM, no WebGL and no `three` in it,
 * so the decision can be argued about in a test instead of in a browser.
 *
 * ## The two numbers, and why they are safe
 *
 * `PREFETCH_HANDOVER_MULTIPLE = 3` and `PREFETCH_REACH_MULTIPLE = 1.5` are not
 * taste. The first puts San Francisco's trigger at 213.6 km, inside the 133 km
 * dead band between California's finest authored rung (242,206 m) and the first
 * Bay rung (71,200 m) — so it fires on a state-scale rung with nothing authored
 * below it, and never at the 1,551 km overview. The second gives discs of 92 km
 * and 146 km around two metros that are 313.9 km apart, and 92 + 146 = 238 <
 * 314, so **at most one tier is ever a candidate**. Both properties are asserted
 * below against the real bounds, because both are load-bearing for a two-deep
 * handheld cache and both would rot silently if a pack's bounds moved.
 */
import assert from "node:assert/strict";
import { describe, it } from "node:test";

import CALIFORNIA from "../cities/california.ts";
import SAN_FRANCISCO from "../cities/sf.ts";
import SOCAL from "../cities/socal.ts";
import { HANDOVER_STANDOFF_M } from "../engine/ladder.ts";
import {
  PREFETCH_HANDOVER_MULTIPLE,
  PREFETCH_REACH_MULTIPLE,
  canAdmit,
  prefetchTarget,
  residentCapacity,
} from "../engine/boards.ts";
import type { PrefetchTier } from "../engine/boards.ts";

const TIERS: readonly PrefetchTier[] = [
  { id: "sf", handoverStandoffM: HANDOVER_STANDOFF_M.sf!, bounds: SAN_FRANCISCO.bounds },
  { id: "socal", handoverStandoffM: HANDOVER_STANDOFF_M.socal!, bounds: SOCAL.bounds },
];

const DESKTOP = residentCapacity(false);
const HANDHELD = residentCapacity(true);

/** The camera parked over each metro's own middle. */
function centre(b: PrefetchTier["bounds"]) {
  return { lat: (b.minLat + b.maxLat) / 2, lng: (b.minLng + b.maxLng) / 2 };
}

const SF_MID = centre(SAN_FRANCISCO.bounds);
const SOCAL_MID = centre(SOCAL.bounds);

function ask(over: { lat: number; lng: number }, standoffM: number, extra: Partial<Parameters<typeof prefetchTarget>[0]> = {}) {
  return prefetchTarget({
    tiers: TIERS,
    lat: over.lat,
    lng: over.lng,
    standoffM,
    resident: ["california"],
    visible: "california",
    capacity: DESKTOP,
    pinned: ["california"],
    ...extra,
  });
}

describe("what the prefetcher arms on", () => {
  it("loads the Bay while the camera is descending toward it", () => {
    assert.equal(ask(SF_MID, HANDOVER_STANDOFF_M.sf! * 2), "sf");
  });

  it("loads the Southland while the camera is descending toward it", () => {
    assert.equal(ask(SOCAL_MID, HANDOVER_STANDOFF_M.socal! * 2), "socal");
  });

  /**
   * The common path, and the reason the free-room rule exists at all.
   *
   * A visitor lands on the state overview at 1,551 km and then clicks a metro.
   * On that path a proximity trigger fires exactly never — the camera is
   * hundreds of kilometres above every threshold and the next thing that happens
   * is the click. A desktop has two empty slots and CONTRACT §1.1 already
   * promises they may be filled, so they are.
   */
  it("fills the free residency from the state overview, where the visitor actually is", () => {
    assert.equal(ask(SF_MID, 1_551_000), "sf");
    // And having taken one, it goes back for the other rather than stopping.
    assert.equal(ask(SF_MID, 1_551_000, { resident: ["california", "sf"] }), "socal");
    // Until there is nothing left to want.
    assert.equal(ask(SF_MID, 1_551_000, { resident: ["california", "sf", "socal"] }), null);
  });

  it("never proposes the board on screen, or one already resident", () => {
    assert.notEqual(ask(SF_MID, HANDOVER_STANDOFF_M.sf! * 2, { visible: "sf" }), "sf");
    assert.notEqual(
      ask(SF_MID, HANDOVER_STANDOFF_M.sf! * 2, { resident: ["california", "sf"] }),
      "sf",
    );
  });

  /**
   * With the cache full, proximity is the only thing that justifies an eviction —
   * and this is the handheld case, capacity two with California pinned. A phone
   * parked on the state board must load nothing at all.
   */
  it("arms nothing on a full handheld cache away from either metro", () => {
    const full = {
      resident: ["california", "sf"],
      visible: "california",
      capacity: HANDHELD,
      pinned: ["california"],
    };
    // Redding, in the far north: nowhere near the Southland.
    assert.equal(ask({ lat: 40.58, lng: -122.39 }, HANDOVER_STANDOFF_M.socal!, full), null);
    // And the state overview, which is above every threshold.
    assert.equal(ask(SOCAL_MID, 1_551_000, full), null);
  });

  it("arms on a full cache only while descending toward the tier it would evict for", () => {
    const full = {
      resident: ["california", "sf"],
      visible: "california",
      capacity: HANDHELD,
      pinned: ["california"],
    };
    assert.equal(ask(SOCAL_MID, HANDOVER_STANDOFF_M.socal! * 2, full), "socal");
  });
});

describe("the two multiples are safe against the real packs", () => {
  /**
   * The dead band. If the Bay's trigger were above California's finest rung the
   * prefetch would fire while the visitor was still choosing a region; if it
   * were below the first Bay rung it would fire too late to have helped.
   */
  it("puts the Bay trigger inside the ladder's authored dead band", () => {
    const trigger = HANDOVER_STANDOFF_M.sf! * PREFETCH_HANDOVER_MULTIPLE;
    assert.ok(trigger > HANDOVER_STANDOFF_M.sf!, "the trigger is below the handover");
    assert.ok(trigger < 242_206, `the Bay trigger ${trigger} is above California's finest rung`);
  });

  /**
   * The covering-set argument, re-derived. Two overlapping discs would mean a
   * camera position from which both metros are candidates, and on a two-deep
   * handheld cache that is one board too many.
   */
  it("gives the two metros discs that cannot overlap", () => {
    const M = 111_320;
    const reach = (b: PrefetchTier["bounds"]) => {
      const mid = (b.minLat + b.maxLat) / 2;
      const north = (b.maxLat - b.minLat) * M;
      const east = (b.maxLng - b.minLng) * M * Math.cos((mid * Math.PI) / 180);
      return (Math.hypot(north, east) / 2) * PREFETCH_REACH_MULTIPLE;
    };
    const gapM =
      (SAN_FRANCISCO.bounds.minLat - SOCAL.bounds.maxLat) * M;
    const together = reach(SAN_FRANCISCO.bounds) + reach(SOCAL.bounds);
    assert.ok(
      SAN_FRANCISCO.bounds.minLat > SOCAL.bounds.maxLat,
      "the metro bounds now intersect — the whole residency argument rests on them not doing so",
    );
    assert.ok(
      together < gapM,
      `the prefetch discs overlap: ${Math.round(together / 1000)} km of reach across a ` +
        `${Math.round(gapM / 1000)} km gap`,
    );
  });

  it("keeps California inside every board's bounds, which is what makes it the pin", () => {
    for (const metro of [SAN_FRANCISCO, SOCAL]) {
      assert.ok(metro.bounds.minLat >= CALIFORNIA.bounds.minLat);
      assert.ok(metro.bounds.maxLat <= CALIFORNIA.bounds.maxLat);
      assert.ok(metro.bounds.minLng >= CALIFORNIA.bounds.minLng);
      assert.ok(metro.bounds.maxLng <= CALIFORNIA.bounds.maxLng);
    }
  });
});

describe("admission never costs the board on screen", () => {
  it("refuses when the only victim left is the visible board", () => {
    // A handheld holding the pin plus the board being looked at is full, and the
    // only thing it could drop is the thing the visitor is looking at.
    assert.equal(
      canAdmit({
        id: "socal",
        resident: ["california", "sf"],
        visible: "sf",
        capacity: HANDHELD,
        pinned: ["california"],
      }),
      false,
    );
  });

  it("admits when a board that is neither pinned nor visible can go", () => {
    assert.equal(
      canAdmit({
        id: "socal",
        resident: ["california", "sf"],
        visible: "california",
        capacity: HANDHELD,
        pinned: ["california"],
      }),
      true,
    );
  });

  it("admits freely below capacity, and is idempotent for a resident board", () => {
    assert.equal(
      canAdmit({ id: "sf", resident: ["california"], visible: "california", capacity: DESKTOP }),
      true,
    );
    assert.equal(
      canAdmit({ id: "sf", resident: ["california", "sf"], visible: "sf", capacity: 2 }),
      true,
    );
  });

  /** And the policy must be reflected in what `prefetchTarget` proposes. */
  it("proposes nothing a full handheld cache could not take", () => {
    assert.equal(
      ask(SOCAL_MID, HANDOVER_STANDOFF_M.socal! * 2, {
        resident: ["california", "sf"],
        visible: "sf",
        capacity: HANDHELD,
        pinned: ["california"],
      }),
      null,
    );
  });
});
