/**
 * src/http/origin.ts — Origin whitelist check (T7)
 *
 * Pure function, no side effects. Security-critical:
 * this is the CSWSH (Cross-Site WebSocket Hijacking) defence described in
 * TECH_DOC §7 and ARCHITECTURE §3.3.
 *
 * Strategy:
 *   - Parse the incoming Origin as a URL.
 *   - Compare scheme + hostname + port against every entry in the allowed list.
 *   - Both host AND port must match (ARCHITECTURE §3.3: "host+port 双匹配").
 *   - undefined Origin (non-browser clients: curl, scripts) → reject by default.
 *     This is the single central policy point — no scattered `if` checks elsewhere.
 */

/**
 * Returns true iff `origin` exactly matches one of the `allowed` origins.
 *
 * Matching is scheme + hostname + port (all three must agree).
 * `undefined` → false (non-browser client; default-deny, no scattered if-chains).
 */
export function isOriginAllowed(
  origin: string | undefined,
  allowed: readonly string[],
): boolean {
  // Central policy: undefined Origin is rejected. No other code path handles this.
  if (origin === undefined || origin === '') {
    return false
  }

  let incomingUrl: URL
  try {
    incomingUrl = new URL(origin)
  } catch {
    // Malformed Origin value → reject.
    return false
  }

  return allowed.some((entry) => {
    let allowedUrl: URL
    try {
      allowedUrl = new URL(entry)
    } catch {
      return false
    }

    return (
      incomingUrl.protocol === allowedUrl.protocol &&
      incomingUrl.hostname === allowedUrl.hostname &&
      incomingUrl.port === allowedUrl.port
    )
  })
}
