/**
 * §4.1 OPEN payload codec — CBOR of MuxOpen, Zod-guarded on decode.
 * Deterministic fixed field order so the byte vector is stable for KAT.
 */
import { ContractDecodeError } from '../errors.js'
import { decodeCborMap, encodeCborMap, type CborMap } from './cbor.js'
import { MuxOpenSchema, type MuxOpen } from './types.js'

/** Frozen deterministic CBOR key order for MuxOpen (§4.1). */
export const MUX_OPEN_KEY_ORDER = [
  'streamId',
  'subdomain',
  'requestPath',
  'originHeader',
  'remoteAddrHash',
  'capabilityTokenRef',
] as const

/** Encode a MuxOpen into its CBOR payload. Validates the shape before encoding. */
export function encodeOpen(open: MuxOpen): Uint8Array {
  const parsed = MuxOpenSchema.parse(open)
  const map: CborMap = {
    streamId: parsed.streamId,
    subdomain: parsed.subdomain,
    requestPath: parsed.requestPath,
    originHeader: parsed.originHeader,
    remoteAddrHash: parsed.remoteAddrHash,
    capabilityTokenRef: parsed.capabilityTokenRef,
  }
  return encodeCborMap(map, MUX_OPEN_KEY_ORDER)
}

/** Decode a CBOR OPEN payload into a validated MuxOpen (throws on bad shape). */
export function decodeOpen(payload: Uint8Array): MuxOpen {
  const raw = decodeCborMap(payload)
  const result = MuxOpenSchema.safeParse(raw)
  if (!result.success) {
    throw new ContractDecodeError(`invalid MuxOpen payload: ${result.error.message}`)
  }
  return result.data
}
