/**
 * Everything a route needs, built once and handed in.
 *
 * Routes get this object rather than reaching for module-level singletons, which
 * is what makes the tests able to stand a whole server up against a fake
 * environment in-process. Each service owns its own cache and its own failure
 * behaviour; none of them can throw at a route.
 */

import { createAuth, type AuthService } from "./auth/index.ts";
import { createDevicesService, type DevicesService } from "./devices/index.ts";
import { createFiresService, type FiresService } from "./fires/index.ts";
import { createFlightsService, type FlightsService } from "./flights/index.ts";
import { createMarkerStore, type MarkerStore } from "./markers/store.ts";
import {
  createIceCredentialProvider,
  createMediaSignalService,
  type IceCredentialProvider,
  type MediaSignalService,
} from "./media/index.ts";
import { createOfficeStore, type OfficeStore } from "./offices/store.ts";
import { createPresenceStore, type PresenceStore } from "./presence/store.ts";
import { createRealtimeService, type RealtimeService } from "./realtime/index.ts";
import { createSatellitesService, type SatellitesService } from "./satellites/index.ts";
import { createWeatherService, type WeatherService } from "./weather/index.ts";
import type { Config } from "./config.ts";

export interface Services {
  config: Config;
  weather: WeatherService;
  flights: FlightsService;
  satellites: SatellitesService;
  fires: FiresService;
  markers: MarkerStore;
  devices: DevicesService;
  media: MediaSignalService;
  ice: IceCredentialProvider;
  offices: OfficeStore;
  presence: PresenceStore;
  realtime: RealtimeService;
  auth: AuthService;
  /** Epoch milliseconds, for `uptimeSeconds` on the health body. */
  startedAt: number;
}

/** The minimum a service needs from a logger. Fastify's satisfies it. */
export interface ServiceLog {
  warn(msg: string): void;
}

export function createServices(config: Config, log: ServiceLog): Services {
  return {
    config,
    weather: createWeatherService(config, log),
    flights: createFlightsService(config, log),
    satellites: createSatellitesService(config, log),
    fires: createFiresService(config, log),
    markers: createMarkerStore(config, log),
    devices: createDevicesService(config, log),
    media: createMediaSignalService(),
    ice: createIceCredentialProvider(config.ice),
    offices: createOfficeStore(config.offices.dir),
    presence: createPresenceStore(config.presence.dir),
    realtime: createRealtimeService(),
    auth: createAuth(config.auth),
    startedAt: Date.now(),
  };
}
