/**
 * env.ts — single source of typed configuration.
 *
 * Per sa-security gate #8: the runtime only reads the allow-listed env vars
 * below. If a future contributor reaches for `process.env.X` directly,
 * add it here first so the surface stays auditable.
 */

function required(key: string): string {
  const v = process.env[key];
  if (!v || !v.trim()) throw new Error(`missing required env: ${key}`);
  return v;
}

function optional(key: string, dflt: string): string {
  return process.env[key]?.trim() || dflt;
}

function int(key: string, dflt: number): number {
  const v = process.env[key];
  if (!v) return dflt;
  const n = Number(v);
  return Number.isFinite(n) ? n : dflt;
}

function number(key: string, dflt: number): number {
  return int(key, dflt);
}

export const env = {
  DATABASE_URL: required("DATABASE_URL"),
  EMBED_SERVICE_URL: optional("EMBED_SERVICE_URL", "http://embed:8000"),
  CLAUDE_CODE_OAUTH_TOKEN: optional("CLAUDE_CODE_OAUTH_TOKEN", ""),
  CASE_ROOT: optional("CASE_ROOT", "/data/ufo/case"),
  WIKI_ROOT: optional("WIKI_ROOT", "/data/ufo/wiki"),
  AUDIT_LOG: optional("AUDIT_LOG", "/data/ufo/case/audit.jsonl"),
  WORKER_ID: optional("WORKER_ID", `investigator-${process.pid}`),
  MAX_PARALLEL_WORKERS: int("MAX_PARALLEL_WORKERS", 2),
  BUDGET_CAP_USD_PER_JOB: number("BUDGET_CAP_USD_PER_JOB", 1.0),
  JOB_TIMEOUT_SECONDS: int("JOB_TIMEOUT_SECONDS", 300),
  CLAUDE_MODEL: optional("CLAUDE_MODEL", "sonnet"),
};
