// The gRPC Length-Prefixed-Message framing (the codec shared by gRPC-Web over
// HTTP/1.1 and real gRPC over HTTP/2): one flag octet, a 4-byte big-endian length,
// then the payload. `encode_message` lays it down and `decode_message` reads it
// back, reporting whether the compression flag was set and handing back the body.
// Only whole frames decode — a short buffer is `None`, the signal a reader uses to
// wait for more bytes.
//
//     moon run src/examples/01-message-framing

///|
fn show(label : String, frame : Bytes) -> Unit {
  match @moonrpc.decode_message(frame) {
    Some((compressed, payload)) =>
      println(
        "\{label}: \{@base16.encode(frame)}  ->  compressed=\{compressed}, \{payload.length()} body octets",
      )
    None => println("\{label}: \{@base16.encode(frame)}  ->  incomplete")
  }
}

///|
#coverage.skip
fn main {
  // The flag octet is 0 for identity and 1 for a compressed body; the length is the
  // body length, not counting the 5-octet prefix.
  let plain = @moonrpc.encode_message(b"heke1228")
  show("identity ", plain)
  let compressed = @moonrpc.encode_message(b"heke1228", compressed=true)
  show("flagged  ", compressed)

  // An empty payload still frames: the 5-octet prefix with a zero length.
  show("empty    ", @moonrpc.encode_message(b""))

  // A reader that has only part of the prefix (or part of the body) gets `None` and
  // waits — the frame is not yet whole.
  match @moonrpc.decode_message(b"\x00\x00\x00") {
    Some(_) => println("partial  : decoded (unexpected)")
    None => println("partial  : 3 octets -> incomplete, wait for more")
  }
  let short = plain[0:plain.length() - 2].to_owned()
  match @moonrpc.decode_message(short) {
    Some(_) => println("truncated: decoded (unexpected)")
    None =>
      println(
        "truncated: length says 8 body octets, only 6 present -> incomplete",
      )
  }

  // The prefix caps the body at `max_message_size`; a decoder rejects a length
  // beyond it rather than allocating on a hostile prefix.
  println("max message size: \{@moonrpc.max_message_size} octets (4 MiB)")
}