/**
 * Parse and validate the `CORS_ALLOWED_ORIGINS` env var into a list
 * of origin strings ready to be passed to `app.enableCors({ origin
 * }) `.
 *
 * Wired in `main.ts` (no eager boot-time pre-flight check — the
 * value is consumed at CORS configuration time, after `NestFactory.
 * create`). The validator runs there to fail fast on a malformed
 * URL.
 *
 * Format: comma-separated list of origins (`<scheme>://<host>[:port]`).
 * Whitespace around each entry is trimmed. Empty entries are
 * filtered out. Trailing slashes are not allowed (an "origin" is
 * scheme+host+port; nothing after).
 *
 * No fallback to a dev default. The BFF refuses to start without
 * an explicit allowlist — getting CORS wrong silently is exactly
 * the kind of "works in dev, breaks in prod" issue this guard is
 * supposed to catch.
 *
 * Production should set `CORS_ALLOWED_ORIGINS` to the SPA / admin
 * SPA's deploy origins (e.g.
 * `https://portal.apf.example,https://admin.portal.apf.example`).
 * Dev `.env` lists `http://localhost:4200` (portal-shell) and
 * `http://localhost:4300` (portal-admin) — see
 * apps/portal-admin/project.json `serve.options.port`.
 */
export function readCorsAllowlist(): readonly string[] {
  const raw = process.env['CORS_ALLOWED_ORIGINS'];
  if (raw === undefined || raw === '') {
    throw new Error(
      `CORS_ALLOWED_ORIGINS is not set. Add the SPA origin(s) to ` +
        `apps/portal-bff/.env, e.g. CORS_ALLOWED_ORIGINS=http://localhost:4200`,
    );
  }

  const origins = raw
    .split(',')
    .map((o) => o.trim())
    .filter((o) => o.length > 0);

  if (origins.length === 0) {
    throw new Error(`CORS_ALLOWED_ORIGINS is empty after parsing: "${raw}"`);
  }

  for (const origin of origins) {
    assertOriginShape(origin);
  }

  return origins;
}

function assertOriginShape(origin: string): void {
  let url: URL;
  try {
    url = new URL(origin);
  } catch {
    throw new Error(`CORS_ALLOWED_ORIGINS entry "${origin}" is not a valid URL`);
  }

  if (url.protocol !== 'http:' && url.protocol !== 'https:') {
    throw new Error(
      `CORS_ALLOWED_ORIGINS entry "${origin}" must use http: or https:, got "${url.protocol}"`,
    );
  }

  if (url.pathname !== '/' && url.pathname !== '') {
    throw new Error(
      `CORS_ALLOWED_ORIGINS entry "${origin}" must be a bare origin ` +
        `(scheme://host[:port]) with no path. Got pathname "${url.pathname}".`,
    );
  }

  if (url.search !== '' || url.hash !== '') {
    throw new Error(
      `CORS_ALLOWED_ORIGINS entry "${origin}" must be a bare origin — no query string or fragment.`,
    );
  }
}
