; Phase 2 — optimistic concurrency: conflict is a real result, not a crash.

(persist-test
  "append-expect 0 on empty stream succeeds"
  (persist/event-seq
    (persist/append-expect
      (persist/open)
      "s"
      0
      "x"
      0
      {}))
  1)
(persist-test
  "append-expect with correct seq succeeds"
  (let
    ((b (persist/open)))
    (begin
      (persist/append b "s" "x" 0 {})
      (persist/event-seq
        (persist/append-expect b "s" 1 "x" 0 {}))))
  2)
(persist-test
  "append-expect with stale seq returns a conflict"
  (let
    ((b (persist/open)))
    (begin
      (persist/append b "s" "x" 0 {})
      (persist/append b "s" "x" 0 {})
      (persist/conflict?
        (persist/append-expect b "s" 1 "x" 0 {}))))
  true)
(persist-test
  "a successful append is not a conflict"
  (persist/conflict?
    (persist/append-expect
      (persist/open)
      "s"
      0
      "x"
      0
      {}))
  false)
(persist-test
  "conflict carries expected and actual"
  (let
    ((b (persist/open)))
    (begin
      (persist/append b "s" "x" 0 {})
      (persist/append b "s" "x" 0 {})
      (let
        ((r (persist/append-expect b "s" 0 "x" 0 {})))
        (list (persist/conflict-expected r) (persist/conflict-actual r)))))
  (list 0 2))
(persist-test
  "a conflicting append does not write"
  (let
    ((b (persist/open)))
    (begin
      (persist/append b "s" "x" 0 {})
      (persist/append-expect b "s" 0 "x" 0 {})
      (persist/count b "s")))
  1)
(persist-test
  "two writers: first wins, second conflicts"
  (let
    ((b (persist/open)))
    (let
      ((seen (persist/last-seq b "s")))
      (begin
        (persist/append-expect b "s" seen "x" 0 {:who "A"})
        (persist/conflict?
          (persist/append-expect b "s" seen "x" 0 {:who "B"})))))
  true)
(persist-test
  "retry after conflict succeeds"
  (let
    ((b (persist/open)))
    (let
      ((seen (persist/last-seq b "s")))
      (begin
        (persist/append-expect b "s" seen "x" 0 {:who "A"})
        (let
          ((r (persist/append-expect b "s" seen "x" 0 {:who "B"})))
          (if
            (persist/conflict? r)
            (persist/event-seq
              (persist/append-expect
                b
                "s"
                (persist/conflict-actual r)
                "x"
                0
                {:who "B"}))
            (persist/event-seq r))))))
  2)
