///|
/// Per-operation security: a route declares `security=[SecurityRequirement]` and
/// the app enforces it *before* the handler. `App::secure_oauth2` both surfaces
/// the scheme in the spec (with its advertised scopes) and registers the guard;
/// `App::set_clock` gives the app the verification time. A request with no token
/// is `401`, a valid token missing the scope is `403`, and the handler only runs
/// once the guard passes — and the requirement is emitted as the operation's
/// OpenAPI `security` array off the same declaration.
///
///     moon run src/examples/11-per-op-security
#coverage.skip
async fn main {
  let secret = "heke1228-signing-secret"
  let bearer = @moonapi.OAuth2PasswordBearer::new("/token", secret)
  let now = 1_700_000_000L
  let app = @moonapi.App::new()
  app.set_clock(() => now)
  app.secure_oauth2("OAuth2", bearer, scopes=[
    ("items:read", "read items"),
    ("items:write", "write items"),
  ])
  // The handler is never reached unless the guard admits the request.
  app.get(
    "/items",
    _ctx => @moonapi.text(200, "the item list"),
    summary="list items",
    security=[
      @moonapi.SecurityRequirement::new("OAuth2", scopes=["items:read"]),
    ],
  )
  let good = @moonapi.create_access_token("lfanke", secret, now, scopes=[
    "items:read",
  ])
  let weak = @moonapi.create_access_token("lfanke", secret, now, scopes=[
    "profile",
  ])
  let hit = (label : String, headers : Array[(String, String)]) => {
    let req : @moonasgi.Request = {
      http_method: "GET",
      path: "/items",
      query_string: b"",
      headers,
      body: b"",
    }
    let r = app.handle(req)
    println(
      "GET /items \{label} -> \{r.status} \{@utf8.decode_lossy(r.body[:])}",
    )
  }
  hit("(no token)", [])
  hit("(items:read)", [("authorization", "Bearer " + good)])
  hit("(profile only)", [("authorization", "Bearer " + weak)])
  println("--- OpenAPI 3.1.0 (operation security + securitySchemes) ---")
  println(app.openapi_json(version=OpenApi31))
}