///|
/// `response_model` — a route holds a richer object than it exposes. `json_model`
/// validates a handler's return value against a declared `Schema` and projects it
/// down to exactly the model's fields, so an internal `password_hash` / `email`
/// never reach the wire; `filter_response` is the same check returning the
/// filtered `Json` or the located errors. `schema_of` reaches a type's descriptor
/// through the `ToSchema` bridge, and `validate_schema` is the low-level conformance
/// check both request and response validation share.
///
///     moon run src/examples/08-response-model
#coverage.skip
async fn main {
  let public_user = @moonapi.Schema::object("PublicUser", [
    @moonapi.Field::new("id", SInt),
    @moonapi.Field::new("name", SStr),
  ])
  let app = @moonapi.App::new()
  app.get("/me", _ctx => {
    // The handler builds a full record; the model decides what leaves.
    let internal : Json = {
      let m : Map[String, Json] = Map([
        ("id", Json(233)),
        ("name", Json("lfanke")),
        ("password_hash", Json("deadbeef")),
        ("email", Json("lfanke@example.com")),
      ])
      Json(m)
    }
    @moonapi.json_model(200, public_user, internal)
  })
  let req : @moonasgi.Request = {
    http_method: "GET",
    path: "/me",
    query_string: b"",
    headers: [],
    body: b"",
  }
  let r = app.handle(req)
  println("GET /me -> \{r.status} \{@utf8.decode_lossy(r.body[:])}")

  // filter_response directly: conforming value keeps only declared fields.
  let ok : Json = {
    let m : Map[String, Json] = Map([
      ("id", Json(1)),
      ("name", Json("qwq")),
      ("secret", Json("hidden")),
    ])
    Json(m)
  }
  match @moonapi.filter_response(public_user, ok) {
    Ok(filtered) => println("filtered -> \{filtered.stringify()}")
    Err(_) => println("unexpected error")
  }

  // A value of the wrong shape (name is a number) fails the model: a 500 body,
  // since a broken return value is a server fault, not the client's.
  let bad : Json = {
    let m : Map[String, Json] = Map([("id", Json(1)), ("name", Json(0))])
    Json(m)
  }
  match @moonapi.filter_response(public_user, bad) {
    Ok(_) => println("unexpected pass")
    Err(errs) =>
      println("rejected -> \{@moonapi.validation_error_body(errs).stringify()}")
  }

  // validate_schema is the shared conformance check underneath.
  let errs : Array[@moonapi.ValidationError] = []
  @moonapi.validate_schema(public_user, ok, ["body"], errs)
  println("validate_schema(ok) errors = \{errs.length()}")

  // schema_of reaches a struct's descriptor through the ToSchema bridge — the
  // same tree its associated `schema()` returns.
  let user : User = {
    id: 233,
    name: "lfanke",
    address: { city: "emm", zip: "23333", },
    tags: ["a", "b"],
  }
  println(
    "schema_of(user) == User::schema(): \{@moonapi.schema_of(user) == User::schema()}",
  )
}