; Extension — global commit ordering across streams.

(persist-test
  "gappend returns the stream event with its local seq"
  (let
    ((b (persist/open)))
    (persist/event-seq
      (persist/gappend b "orders" "placed" 0 {})))
  1)
(persist-test
  "global-pos advances per gappend regardless of stream"
  (let
    ((b (persist/open)))
    (begin
      (persist/gappend b "orders" "placed" 0 {})
      (persist/gappend b "users" "joined" 0 {})
      (persist/gappend b "orders" "placed" 0 {})
      (persist/global-pos b)))
  3)
(persist-test
  "read-global returns events in commit order across streams"
  (let
    ((b (persist/open)))
    (begin
      (persist/gappend b "orders" "placed" 0 {:n 1})
      (persist/gappend b "users" "joined" 0 {:n 2})
      (persist/gappend b "orders" "placed" 0 {:n 3})
      (let
        ((g (persist/read-global b)))
        (list
          (get (persist/event-data (nth g 0)) :n)
          (get (persist/event-data (nth g 1)) :n)
          (get (persist/event-data (nth g 2)) :n)))))
  (list 1 2 3))
(persist-test
  "read-global resolves to the right streams"
  (let
    ((b (persist/open)))
    (begin
      (persist/gappend b "orders" "placed" 0 {})
      (persist/gappend b "users" "joined" 0 {})
      (let
        ((g (persist/read-global b)))
        (list
          (persist/event-stream (nth g 0))
          (persist/event-stream (nth g 1))))))
  (list "orders" "users"))
(persist-test
  "project-global folds across all streams in order"
  (let
    ((b (persist/open)))
    (begin
      (persist/gappend b "a" "x" 0 {:v 10})
      (persist/gappend b "b" "x" 0 {:v 20})
      (persist/gappend b "a" "x" 0 {:v 30})
      (persist/project-global
        b
        (fn (acc e) (+ acc (get (persist/event-data e) :v)))
        0)))
  60)
(persist-test
  "global index is hidden from the public catalog"
  (let
    ((b (persist/open)))
    (begin
      (persist/gappend b "orders" "placed" 0 {})
      (persist/gappend b "users" "joined" 0 {})
      (list (persist/stream-count b) (persist/stream-exists? b "$global"))))
  (list 2 false))
(persist-test
  "streams-all reveals the reserved index"
  (let
    ((b (persist/open)))
    (begin
      (persist/gappend b "orders" "placed" 0 {})
      (contains? (persist/streams-all b) "$global")))
  true)
(persist-test
  "global-from gives pointers at or after a position"
  (let
    ((b (persist/open)))
    (begin
      (persist/gappend b "a" "x" 0 {})
      (persist/gappend b "a" "x" 0 {})
      (persist/gappend b "a" "x" 0 {})
      (len (persist/global-from b 2))))
  2)
(persist-test
  "plain append does not touch the global index"
  (let
    ((b (persist/open)))
    (begin
      (persist/append b "orders" "placed" 0 {})
      (persist/gappend b "orders" "placed" 0 {})
      (persist/global-pos b)))
  1)
(persist-test
  "global ordering works on the durable backend"
  (let
    ((db (persist/mock-durable (persist/mem-backend))))
    (begin
      (persist/gappend db "a" "x" 0 {:v 1})
      (persist/gappend db "b" "x" 0 {:v 2})
      (persist/project-global
        db
        (fn (acc e) (+ acc (get (persist/event-data e) :v)))
        0)))
  3)
(persist-test
  "global order survives restart (determinism)"
  (let
    ((disk (persist/mem-backend)))
    (begin
      (let
        ((db (persist/mock-durable disk)))
        (begin
          (persist/gappend db "a" "x" 0 {:v 1})
          (persist/gappend db "b" "x" 0 {:v 2})))
      (persist/project-global
        (persist/mock-durable disk)
        (fn (acc e) (+ acc (get (persist/event-data e) :v)))
        0)))
  3)
