;; lib/host/handler.sx — Host handler layer: the bridge from a Dream request to a
;; subsystem call and back to a Dream response. A host handler IS a Dream handler
;; (request -> response); these helpers build the SX-native envelope every host
;; endpoint shares — text/sx, serialized SX wire format (NOT JSON): {:ok true
;; :data ...} on success, {:ok false :error ...} on failure. The platform speaks
;; SX end to end; JSON lives only at the ActivityPub federation edge (JSON-LD).
;; Depends on lib/dream/types.sx.

;; ── responses ──────────────────────────────────────────────────────

;; SX response at an arbitrary status: content-type text/sx, body = the value
;; serialized to SX wire format (the same `serialize` SXTP uses). The SX engine /
;; WASM kernel parses this directly — NO JSON on the internal wire.
(define host/sx-status
  (fn (status value)
    (dream-response status {:content-type "text/sx; charset=utf-8"}
      (serialize value))))

;; Success envelope: 200 {:ok true :data <value>}.
(define host/ok
  (fn (value)
    (host/sx-status 200 {:ok true :data value})))

;; Success envelope at a chosen status (e.g. 201 for a created resource).
(define host/ok-status
  (fn (status value)
    (host/sx-status status {:ok true :data value})))

;; Error envelope: {:ok false :error <message>} at the given status.
(define host/error
  (fn (status message)
    (host/sx-status status {:ok false :error message})))

;; ── request reading ────────────────────────────────────────────────

;; Integer query param with a fallback (query params arrive as strings).
;; Absent param -> fallback; present -> parsed number.
(define host/query-int
  (fn (req name fallback)
    (let ((raw (dream-query-param req name)))
      (if raw (string->number raw) fallback))))
