/**
 * Cookie parse + Set-Cookie serialization — dependency-light (no @fastify/cookie), mirroring the
 * base app's src/http/auth.ts discipline. Values are returned verbatim (NOT URL-decoded); the
 * session token uses a cookie-safe charset (base64url + '.') so there is nothing to decode.
 */

/** The panel session cookie name. HttpOnly (JS can't read it → XSS can't exfiltrate it). */
export const SESSION_COOKIE_NAME = 'panel_session'

/**
 * Parse a raw `Cookie:` header into a name→value map. Malformed pairs (no `=`, empty name) are
 * ignored; last write wins on duplicate names.
 */
export function parseCookieHeader(header: string | undefined): Record<string, string> {
  const out: Record<string, string> = {}
  if (header === undefined || header === '') return out
  for (const part of header.split(';')) {
    const eq = part.indexOf('=')
    if (eq <= 0) continue
    const name = part.slice(0, eq).trim()
    if (name === '') continue
    out[name] = part.slice(eq + 1).trim()
  }
  return out
}

interface SetCookieOptions {
  readonly value: string
  readonly maxAgeSec: number
  readonly secure: boolean
}

/**
 * Build a `Set-Cookie` value. Flags: HttpOnly (no JS read), SameSite=Strict (cross-site pages can't
 * ride the cookie — CSRF/CSWSH defence), Path=/, Max-Age, and Secure ONLY when `secure` (a Secure
 * cookie is never sent over http:// — forcing it would break a loopback/http operator session).
 */
export function buildSetCookie(opts: SetCookieOptions): string {
  const parts = [
    `${SESSION_COOKIE_NAME}=${opts.value}`,
    'Path=/',
    `Max-Age=${opts.maxAgeSec}`,
    'HttpOnly',
    'SameSite=Strict',
  ]
  if (opts.secure) parts.push('Secure')
  return parts.join('; ')
}

/** Build a `Set-Cookie` that immediately expires the session cookie (logout). */
export function buildClearCookie(opts: { secure: boolean }): string {
  return buildSetCookie({ value: '', maxAgeSec: 0, secure: opts.secure })
}
