// Copyright 2026 Leo Cheng
// SPDX-License-Identifier: Apache-2.0

///|
/// The two headers a hop reads and the three it writes, over the same carrier: an
/// array of name and value pairs, which is what an ASGI scope and an HTTP client's
/// header list both are.
///
///     moon run src/examples/01-propagate
#coverage.skip
fn main {
  let inbound = [
    ("traceparent", "00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01"),
    ("tracestate", "vendor=abc"),
    ("baggage", "userId=alice,note=caf%C3%A9"),
    ("accept", "application/json"),
  ]
  println("inbound")
  for header in inbound {
    println("  \{header.0}: \{header.1}")
  }

  // What the hop understood: the trace to join, and the bag that came with it.
  let extracted = @propagate.extract(inbound)
  println("")
  println(
    match extracted.context {
      Some(context) => "joined trace \{context.to_traceparent()}"
      None => "no usable context, this hop starts a trace"
    },
  )
  println("baggage: \{extracted.baggage.to_header()}")

  // A span of this hop's own, under whatever context arrived.
  let tracer = @trace.Tracer::new(
    rand=random_bytes,
    sink=@trace.Recorder::new(),
    sampler=@trace.parent_based(root=@trace.always),
  )
  let span = match extracted.context {
    Some(parent) =>
      tracer.start("publish", parent~, kind=@trace.Client, at=1L) catch {
        _ => abort("the platform has no entropy source")
      }
    None =>
      tracer.start("publish", kind=@trace.Client, at=1L) catch {
        _ => abort("the platform has no entropy source")
      }
  }
  span.finish(at=2L)

  // The next request carries this hop's span as its parent, and the bag unchanged.
  let outgoing = @propagate.inject(inbound, {
    context: Some(span.context()),
    baggage: extracted.baggage,
  })
  println("")
  println("outgoing")
  for header in outgoing {
    println("  \{header.0}: \{header.1}")
  }
}

///|
fn random_bytes(width : Int32) -> Bytes {
  @moonseed.bytes(width, @system.source) catch {
    _ => abort("the platform has no entropy source")
  }
}