;; content-on-sx — public API facade.
;;
;; The stable surface other code calls. Composes block + doc + render. Document
;; values are immutable; every edit returns a new document, so callers hold
;; explicit versions (the persist op log in Phase 2 becomes the source of truth).
;;
;; Requires (loaded by the harness): block.sx, doc.sx, render.sx and a base
;; Smalltalk class table (st-bootstrap-classes!).

;; Register the content class hierarchy + render methods. Caller bootstraps the
;; base Smalltalk classes first; this only adds content classes (idempotent).
(define
  content/bootstrap!
  (fn
    ()
    (begin
      (content-bootstrap-blocks!)
      (content-bootstrap-doc!)
      (content-bootstrap-render!)
      true)))

;; ── documents ──
(define content/new doc-new)
(define content/empty doc-empty)
(define content/append doc-append)
(define content/blocks doc-blocks)
(define content/count doc-count)
;; find / has? are TREE-WIDE by id (descend into sections) — so the facade reads
;; back any block content/edit can update or delete. content/find-top / has-top?
;; keep the top-level-only lookup for callers that mean the ordered sequence.
(define content/find doc-find-deep)
(define content/has? doc-has-deep?)
(define content/find-top doc-find)
(define content/has-top? doc-has?)
(define content/ids doc-ids)
(define content/types doc-types)

;; ── blocks ──
(define content/block mk-block)

;; ── edit ops (data payload) ──
(define content/insert op-insert)
(define content/update op-update)
(define content/move op-move)
(define content/delete op-delete)

(define content/op? (fn (x) (and (dict? x) (has-key? x :op))))

;; edit — apply one op or a stream of ops; returns a new document.
(define
  content/edit
  (fn
    (doc ops)
    (if (content/op? ops) (doc-apply doc ops) (doc-apply-all doc ops))))

;; ── render boundary ──
;; fmt is "html"/"sx"/"md"/"text" (or the matching keyword). "md" needs
;; markdown.sx loaded; "text" needs text.sx loaded.
(define
  content/render
  (fn
    (doc fmt)
    (cond
      ((= fmt "html") (asHTML doc))
      ((= fmt "sx") (asSx doc))
      ((= fmt "md") (asMarkdown doc))
      ((= fmt "markdown") (asMarkdown doc))
      ((= fmt "text") (asText doc))
      (else (error (str "unknown render format: " fmt))))))

(define content/html asHTML)
(define content/sx asSx)
