export { BaseArenaEnvironment, type SimulationTransition } from "./base.ts";
export {
  ARENA_CHECKSUM_DECIMALS,
  arenaChecksum,
  canonicalJson,
  quantizeForChecksum,
  quantizeToPlaces,
} from "./checksum.ts";
export { ArenaRandom, deriveArenaSeed, normalizeArenaSeed } from "./random.ts";
export {
  ArenaScenarioRegistry,
  type ArenaScenarioDefinition,
  type ScenarioSampler,
} from "./scenarios.ts";
export { ARENA_SOURCE_HASHES } from "./sourceHashes.ts";
export {
  actionWidth,
  arenaEnvironmentIds,
  arenaFieldWidth,
  arenaManifest,
  flattenAction,
  flattenObservation,
  observationWidth,
  structureAction,
} from "./spaces.ts";
export { rollout, type ArenaPolicy, type RolloutOptions, type RolloutResult } from "./rollout.ts";
export {
  ARENA_API_VERSION,
  type ArenaEnvironment,
  type ArenaFieldKind,
  type ArenaFieldSpec,
  type ArenaInfo,
  type ArenaManifest,
  type ArenaReplayResult,
  type ArenaResetResult,
  type ArenaScenario,
  type ArenaScenarioRequest,
  type ArenaSnapshot,
  type ArenaSourceHashes,
  type ArenaSplit,
  type ArenaStepResult,
  type ArenaTraceEnvelope,
  type ArenaTraceStep,
} from "./types.ts";

export {
  DRIVE_101_MANIFEST,
  DRIVE_101_SCENARIOS,
  DRIVE_INACTION,
  Drive101Environment,
  driveScriptedBaseline,
  type DriveAction,
  type DriveObservation,
  type DriveReward,
} from "./drive101.ts";
export {
  OFFICE_NAV_INACTION,
  OFFICE_NAV_MANIFEST,
  OFFICE_NAV_SCENARIOS,
  OfficeNavEnvironment,
  officeNavScriptedBaseline,
  type OfficeNavAction,
  type OfficeNavObservation,
  type OfficeNavReward,
} from "./officeNav.ts";
export {
  OFFICE_JOBS_INACTION,
  OFFICE_JOBS_MANIFEST,
  OFFICE_JOBS_SCENARIOS,
  OfficeJobsEnvironment,
  officeJobsScriptedBaseline,
  type OfficeJobsAction,
  type OfficeJobsObservation,
  type OfficeJobsReward,
} from "./officeJobs.ts";
export {
  CROW_NAV_INACTION,
  CROW_NAV_MANIFEST,
  CROW_NAV_SCENARIOS,
  CrowNavEnvironment,
  crowNavScriptedBaseline,
  type CrowNavAction,
  type CrowNavObservation,
  type CrowNavReward,
} from "./crowNav.ts";
export {
  CALIFORNIA_FLIGHT_INACTION,
  CALIFORNIA_FLIGHT_MANIFEST,
  CALIFORNIA_FLIGHT_SCENARIOS,
  CaliforniaFlightEnvironment,
  californiaFlightScriptedBaseline,
  type CaliforniaFlightAction,
  type CaliforniaFlightObservation,
  type CaliforniaFlightReward,
} from "./californiaFlight.ts";
export {
  STUDIO_OPS_INACTION,
  STUDIO_OPS_MANIFEST,
  STUDIO_OPS_SCENARIOS,
  StudioOpsEnvironment,
  localSolarHour,
  quantizeObservable,
  studioDeviceKw,
  studioHvacKw,
  studioOpsEnergyPenalty,
  studioOpsNoisePenalty,
  studioOpsScriptedBaseline,
  studioOverflights,
  studioSkyAt,
  studioSolarKw,
  studioVehicleReadiness,
  studioWeatherAt,
  weatherConditionOf,
  type OverflightTrack,
  type StudioNoiseInput,
  type StudioOpsAction,
  type StudioOpsObservation,
  type StudioOpsReward,
  type StudioOpsScenarioParameters,
  type StudioSky,
  type StudioWeather,
} from "./studioOps.ts";

import { CALIFORNIA_FLIGHT_MANIFEST, CaliforniaFlightEnvironment } from "./californiaFlight.ts";
import { CROW_NAV_MANIFEST, CrowNavEnvironment } from "./crowNav.ts";
import { DRIVE_101_MANIFEST, Drive101Environment } from "./drive101.ts";
import { OFFICE_NAV_MANIFEST, OfficeNavEnvironment } from "./officeNav.ts";
import { OFFICE_JOBS_MANIFEST, OfficeJobsEnvironment } from "./officeJobs.ts";
import { STUDIO_OPS_MANIFEST, StudioOpsEnvironment } from "./studioOps.ts";
import type { ArenaEnvironment } from "./types.ts";

/** Machine-readable public environment catalogue. */
export const ARENA_MANIFESTS = Object.freeze([
  DRIVE_101_MANIFEST,
  OFFICE_NAV_MANIFEST,
  OFFICE_JOBS_MANIFEST,
  CROW_NAV_MANIFEST,
  CALIFORNIA_FLIGHT_MANIFEST,
  STUDIO_OPS_MANIFEST,
]);

/**
 * Env id to constructor.
 *
 * `ARENA_MANIFESTS` describes six environments and, until this existed, gave a
 * harness no supported way to *build* any of them: a caller handed the string
 * `"drive-101-v1"` — off a config file, a command line, a results table — had
 * to maintain its own switch mapping ids to classes, which is a copy of this
 * catalogue kept outside the package and silently wrong the day a sixth
 * environment lands. Which is today.
 *
 * Constructors rather than instances, because an `ArenaEnvironment` is
 * stateful: two rollouts in flight need two objects, and a frozen map of shared
 * singletons would have them stepping each other's episodes.
 *
 * `any` in the value type is deliberate and is the one place in this package it
 * appears. A registry keyed by a runtime string cannot promise a caller which
 * action and observation types it will get back — that is the nature of a
 * dynamic lookup — and the alternative is a union that every consumer would
 * immediately have to narrow by the same string it just looked up. A caller
 * that knows the type imports the class.
 */
export const ARENA_ENVIRONMENTS: Readonly<
  Record<string, () => ArenaEnvironment<any, any, Record<string, number>, any>>
> = Object.freeze({
  "drive-101-v1": () => new Drive101Environment(),
  "office-nav-v1": () => new OfficeNavEnvironment(),
  "office-jobs-v1": () => new OfficeJobsEnvironment(),
  "crow-nav-v1": () => new CrowNavEnvironment(),
  "california-flight-v1": () => new CaliforniaFlightEnvironment(),
  "studio-ops-v1": () => new StudioOpsEnvironment(),
});
