/**
 * §4.3 FIX 5 — WS-upgrade capability-token transport over `Sec-WebSocket-Protocol`.
 *
 * The browser's native WebSocket API cannot set request headers, so the token rides the
 * subprotocol list: the client opens
 *   new WebSocket(url, [APP_SUBPROTOCOL, TOKEN_SUBPROTOCOL_PREFIX + base64url(rawToken)])
 * The relay reads the token from the `term.token.<b64u>` entry, strips it before verify, and
 * echoes ONLY `term.relay.v1` back — echoing the token would leak the bearer secret.
 */
import { encodeBase64UrlString, decodeBase64UrlString } from '../base64url.js'

/** The app subprotocol — the ONLY value ever accepted/echoed in the handshake response. */
export const APP_SUBPROTOCOL = 'term.relay.v1' as const

/** The token entry = this prefix + base64url(rawToken). */
export const TOKEN_SUBPROTOCOL_PREFIX = 'term.token.' as const

/** Build the token subprotocol entry: `term.token.` + base64url(rawToken). */
export function encodeTokenSubprotocol(rawToken: string): string {
  return TOKEN_SUBPROTOCOL_PREFIX + encodeBase64UrlString(rawToken)
}

/**
 * Extract the raw token from a subprotocol list: find the `term.token.` entry, strip the
 * prefix, base64url-decode. Returns null if absent (caller rejects with 401). Ignores the
 * app-subprotocol entry. Throws ContractDecodeError if the entry exists but is malformed.
 */
export function extractTokenFromSubprotocols(values: readonly string[]): string | null {
  const entry = values.find((v) => v.startsWith(TOKEN_SUBPROTOCOL_PREFIX))
  if (entry === undefined) return null
  const encoded = entry.slice(TOKEN_SUBPROTOCOL_PREFIX.length)
  return decodeBase64UrlString(encoded)
}
