import type { CookieOptions } from 'express';

/**
 * Name of the CSRF cookie that pairs with the `__Host-portal_session`
 * cookie. Per ADR-0009 §"Double-submit CSRF": the BFF generates a
 * random token at session creation and writes it both to the session
 * payload (server-side) and to this cookie (readable by the SPA).
 * Every mutating request must echo the value back in an
 * `X-CSRF-Token` header; the middleware compares the header against
 * the *session-stored* token, not the cookie — the cookie is just
 * the SPA's UX way of reading the value it's expected to send back.
 *
 * Same env-conditional naming as the session cookie:
 *   - production: `__Host-portal_csrf` (prefix mandates Secure +
 *     Path=/ + no Domain — defeats subdomain cookie injection)
 *   - development: `portal_csrf` (no Secure available on HTTP)
 */
const PRODUCTION_NAME = '__Host-portal_csrf';
const DEVELOPMENT_NAME = 'portal_csrf';

export function csrfCookieName(): string {
  return process.env['NODE_ENV'] === 'production' ? PRODUCTION_NAME : DEVELOPMENT_NAME;
}

/**
 * Cookie options for the CSRF cookie.
 *
 * Crucially **NOT** `HttpOnly`: the SPA needs JavaScript access to
 * read the token and echo it back in the `X-CSRF-Token` header. The
 * tradeoff is acceptable because the cookie is _not_ the auth
 * credential — the session id cookie (`__Host-portal_session`, which
 * IS HttpOnly) is. An XSS that reads this CSRF cookie still cannot
 * impersonate the user without also stealing the session cookie.
 *
 * `SameSite=Lax` (not Strict): matches the session cookie so the
 * two travel together on the SPA→BFF cross-origin same-site fetch
 * (different ports = different origin but same registrable domain).
 * Strict would drop on top-level POST navigations originating from
 * a different origin, which is correct for raw CSRF defense but
 * loses parity with the session cookie's policy. The double-submit
 * pattern itself is what gives the protection here; SameSite=Lax is
 * a belt-and-braces layer.
 */
export function csrfCookieOptions(maxAgeMs: number): CookieOptions {
  const isProduction = process.env['NODE_ENV'] === 'production';
  return {
    httpOnly: false,
    sameSite: 'lax',
    secure: isProduction,
    path: '/',
    maxAge: maxAgeMs,
  };
}
