///|
fn report(label : String, decision : @retry.Decision) -> Unit {
  match decision {
    Wait(ms) => println("\{label}: wait \{ms} ms")
    Stop(_) => println("\{label}: stop")
  }
}

///|
/// Three complete deterministic policy scenarios. No real requests or sleeps.
fn main {
  let settings = @retry.defaults()
  // A rate-limited GET: a server floor survives even the minimum jitter draw.
  let rate_limited = @retry.decide_response(
    settings,
    http_method="GET",
    status=429,
    retry_index=0,
    elapsed_ms=100L,
    body_replayable=true,
    retry_after_values=["5"],
    now_seconds=0L,
    sample_ppm=0,
  )
  report("rate-limited GET", rate_limited)
  // A POST is allowed only when the caller knows server-side deduplication
  // exists and retains the exact body and the same idempotency key.
  let replay_safe_post = @retry.decide(
    settings,
    http_method="POST",
    status=503,
    retry_index=1,
    elapsed_ms=2000L,
    body_replayable=true,
    replay_safe=true,
    sample_ppm=500000,
  )
  report("deduplicated POST", replay_safe_post)
  // A 503 date asks for five seconds but only 1.5 seconds remain: stop.
  let deadline = @retry.decide_response(
    settings,
    http_method="GET",
    status=503,
    retry_index=0,
    elapsed_ms=118500L,
    body_replayable=true,
    retry_after_values=["Thu, 01 Jan 1970 00:00:05 GMT"],
    now_seconds=0L,
  )
  report("deadline exhausted", deadline)
}