/**
 * Composition profile selector (ADR 013).
 *
 * Reads APP_PROFILE at boot, loads the matching profile, validates it via
 * Zod, and freezes it. Callers consume the loaded profile via `getProfile()`.
 *
 * Booting with an unknown or invalid profile fails fast — the process exits
 * before the app can serve a request.
 */

import defaultProfile from "./default";
import bmwProfile from "./bmw"; // allow-customer-string
import templateProfile from "./_template";
import { type CompositionProfile, validateProfile } from "./profile";
import { logger } from "@/lib/logger";

// Customer-profile registry. Each entry is the only sanctioned place where the
// product core knows a customer name — adapter resolution happens via the
// matching `lib/customers/<name>/` zone.
const PROFILES: Record<string, CompositionProfile> = {
  default: defaultProfile,
  bmw: bmwProfile, // allow-customer-string
  _template: templateProfile,
};

let active: Readonly<CompositionProfile> | null = null;

export function loadProfile(name?: string): CompositionProfile {
  const envName = process.env.APP_PROFILE;
  const resolvedName = name ?? envName ?? "default";
  // Silent-fallback risk (see docs/foundation/environment-variables.md,
  // CHANGELOG 2026-07-17): if neither an explicit argument nor APP_PROFILE
  // was set, we just booted into "default" without anyone deciding to. That
  // is fine for local/dev, but for a customer deployment it silently
  // re-enables every feature flag that customer's profile opted out of
  // (e.g. FB-36/FB-41). Warn instead of failing so the pre-existing "unset
  // -> default" fallback behavior is unchanged, just no longer silent.
  if (name === undefined && envName === undefined) {
    logger.warn("profile.app_profile_unset_fallback_default", { resolvedName });
  }
  const profile = PROFILES[resolvedName];
  if (!profile) {
    throw new Error(
      `Unknown APP_PROFILE="${resolvedName}". Available: ${Object.keys(PROFILES).join(", ")}. See ADR 013.`,
    );
  }
  const validated = validateProfile(profile);
  if (!validated.ok) {
    throw new Error(`Composition profile "${resolvedName}" failed validation:\n${validated.error}`);
  }
  // _template is for copying, never for booting a real app.
  if (validated.profile.name === "_template") {
    throw new Error(`Refusing to boot with profile "_template". Copy it as a customer-specific profile first.`);
  }
  active = Object.freeze(validated.profile);
  return active;
}

export function getProfile(): Readonly<CompositionProfile> {
  if (!active) return loadProfile();
  return active;
}

export function listProfileNames(): string[] {
  return Object.keys(PROFILES);
}

export { type CompositionProfile } from "./profile";
