export type ApiPersistence = 'postgres' | 'inmemory';

function isTruthyEnv(value: string | undefined): boolean {
  if (!value) return false;
  return value !== '0' && value.toLowerCase() !== 'false';
}

function isSet(value: string | undefined): boolean {
  return value !== undefined;
}

function readLower(name: string): string | undefined {
  const raw = process.env[name];
  if (raw === undefined) return undefined;
  return raw.toLowerCase();
}

function requireOneOf<T extends string>(name: string, value: string, allowed: readonly T[]): T {
  if ((allowed as readonly string[]).includes(value)) {
    return value as T;
  }

  const valid = allowed.join(', ');
  throw new Error(`Invalid ${name}: "${value}". Must be one of: ${valid}`);
}

/**
 * Controls whether the API uses Postgres or runs in-memory.
 *
 * If `GRIDPILOT_API_PERSISTENCE` is set, it must be `postgres|inmemory`.
 * Otherwise, it falls back to: `postgres` when `DATABASE_URL` exists, else `inmemory`.
 */
export function getApiPersistence(): ApiPersistence {
  const configured = readLower('GRIDPILOT_API_PERSISTENCE');
  if (configured) {
    return requireOneOf('GRIDPILOT_API_PERSISTENCE', configured, ['postgres', 'inmemory'] as const);
  }

  // Tests should default to in-memory even when DATABASE_URL exists, unless explicitly overridden.
  if (process.env.NODE_ENV === 'test') {
    return 'inmemory';
  }

  return process.env.DATABASE_URL ? 'postgres' : 'inmemory';
}

/**
 * Keep bootstrap on by default; tests can disable explicitly.
 *
 * `GRIDPILOT_API_BOOTSTRAP` uses "truthy" parsing:
 * - false when unset / "0" / "false"
 * - true otherwise
 */
export function getEnableBootstrap(): boolean {
  const raw = process.env.GRIDPILOT_API_BOOTSTRAP;
  if (raw === undefined) return true;
  return isTruthyEnv(raw);
}

/**
 * Force reseeding of racing data in development mode.
 *
 * `GRIDPILOT_API_FORCE_RESEED` uses "truthy" parsing:
 * - false when unset / "0" / "false"
 * - true otherwise
 *
 * Only works in non-production environments.
 */
export function getForceReseed(): boolean {
  const raw = process.env.GRIDPILOT_API_FORCE_RESEED;
  if (raw === undefined) return false;
  return isTruthyEnv(raw);
}

/**
 * When set, the API will generate `openapi.json` and optionally reduce logging noise.
 *
 * Matches previous behavior: any value (even "0") counts as enabled if the var is present.
 */
export function getGenerateOpenapi(): boolean {
  return isSet(process.env.GENERATE_OPENAPI);
}