; portable wire form: dag <-> records <-> string, with content-id integrity.

(define ser-RT (artdag/op-table-runner {:in (fn (p i) (get p :v)) :add (fn (p i) (+ (nth i 0) (nth i 1))) :inc (fn (p i) (+ 1 (first i)))}))

(define
  ser-D
  (artdag/build
    (list
      (list "a" "in" (list) {:v 10})
      (list "b" "inc" (list "a") {})
      (list "c" "add" (list "a" "b") {} true))))

(define ser-cid (artdag/dag-id ser-D "c"))

; ---- wire form ----

(artdag-test
  "wire has one record per node"
  (len (artdag/dag->wire ser-D))
  3)

(artdag-test
  "wire records follow topological order"
  (map (fn (rec) (nth rec 0)) (artdag/dag->wire ser-D))
  (artdag/dag-order ser-D))

(artdag-test
  "wire record carries the content-id"
  (nth (nth (artdag/dag->wire ser-D) 0) 0)
  (artdag/dag-id ser-D "a"))

; ---- reconstruction ----

(artdag-test
  "wire->dag restores node count"
  (artdag/node-count (artdag/wire->dag (artdag/dag->wire ser-D)))
  3)

(artdag-test
  "wire->dag restores order"
  (artdag/dag-order (artdag/wire->dag (artdag/dag->wire ser-D)))
  (artdag/dag-order ser-D))

(artdag-test
  "reconstructed leaf inputs normalize to empty list"
  (artdag/node-inputs
    (artdag/dag-get
      (artdag/wire->dag (artdag/dag->wire ser-D))
      (artdag/dag-id ser-D "a")))
  (list))

(artdag-test
  "reconstructed node preserves inputs"
  (artdag/node-inputs
    (artdag/dag-get (artdag/wire->dag (artdag/dag->wire ser-D)) ser-cid))
  (artdag/node-inputs (artdag/dag-get ser-D ser-cid)))

(artdag-test
  "reconstructed node id matches recomputed content-id"
  (artdag/content-id
    (artdag/dag-get (artdag/wire->dag (artdag/dag->wire ser-D)) ser-cid))
  ser-cid)

; ---- execution equivalence ----

(artdag-test
  "reconstructed dag executes to same result"
  (let
    ((c1 (persist/open)) (c2 (persist/open)))
    (=
      (artdag/result-of (artdag/run ser-D ser-RT c1) ser-cid)
      (artdag/result-of
        (artdag/run (artdag/wire->dag (artdag/dag->wire ser-D)) ser-RT c2)
        ser-cid)))
  true)

(artdag-test
  "string round-trip executes to same result"
  (let
    ((cache (persist/open)))
    (artdag/result-of
      (artdag/run
        (artdag/string->dag (artdag/dag->string ser-D))
        ser-RT
        cache)
      ser-cid))
  21)

; ---- integrity ----

(artdag-test
  "wire-verify accepts a genuine wire form"
  (artdag/wire-verify (artdag/dag->wire ser-D))
  true)

(artdag-test
  "wire-verify rejects a tampered id"
  (artdag/wire-verify
    (list (list "node:bogus" "in" (list) {:v 1} false)))
  false)

(artdag-test
  "wire-verify rejects mutated params under a stale id"
  (artdag/wire-verify
    (map
      (fn
        (rec)
        (list
          (nth rec 0)
          (nth rec 1)
          (nth rec 2)
          {:v 999}
          (nth rec 4)))
      (artdag/dag->wire ser-D)))
  false)
