; Phase 3 — Plan: topological batches under a parallelism cap, incremental plan.

; diamond:  a -> b, a -> c, (b,c) -> d
(define
  pl-D
  (artdag/build
    (list
      (list "a" "load" (list) {})
      (list "b" "f" (list "a") {})
      (list "c" "g" (list "a") {})
      (list "d" "add" (list "b" "c") {} true))))
(define pl-a (artdag/dag-id pl-D "a"))
(define pl-b (artdag/dag-id pl-D "b"))
(define pl-c (artdag/dag-id pl-D "c"))
(define pl-d (artdag/dag-id pl-D "d"))

; wide:  a -> b, c, e, f  (four independent dependents)
(define
  pl-W
  (artdag/build
    (list
      (list "a" "load" (list) {})
      (list "b" "f" (list "a") {})
      (list "c" "g" (list "a") {})
      (list "e" "h" (list "a") {})
      (list "f" "k" (list "a") {}))))

; ---- full plan, unlimited width ----

(artdag-test
  "full plan: batch count"
  (artdag/plan-batches (artdag/plan pl-D 0))
  3)

(artdag-test
  "full plan: schedules every node"
  (artdag/plan-size (artdag/plan pl-D 0))
  4)

(artdag-test
  "full plan: first batch is the leaf"
  (first (artdag/plan pl-D 0))
  (list pl-a))

(artdag-test
  "full plan: middle batch runs b,c in parallel"
  (first (rest (artdag/plan pl-D 0)))
  (artdag/sort-strings (list pl-b pl-c)))

(artdag-test
  "full plan: last batch is the sink"
  (first (rest (rest (artdag/plan pl-D 0))))
  (list pl-d))

(artdag-test
  "full plan: max width is 2"
  (artdag/plan-width (artdag/plan pl-D 0))
  2)

; ---- parallelism cap ----

(artdag-test
  "cap 1: width never exceeds 1"
  (artdag/plan-width (artdag/plan pl-D 1))
  1)

(artdag-test
  "cap 1: serializes into one node per batch"
  (artdag/plan-batches (artdag/plan pl-D 1))
  4)

(artdag-test
  "cap larger than widest wave is a no-op"
  (artdag/plan pl-D 10)
  (artdag/plan pl-D 0))

(artdag-test
  "wide cap 2: width capped at 2"
  (artdag/plan-width (artdag/plan pl-W 2))
  2)

(artdag-test
  "wide cap 2: leaf wave then two capped sub-batches"
  (artdag/plan-batches (artdag/plan pl-W 2))
  3)

(artdag-test
  "wide cap 2: still schedules all five nodes"
  (artdag/plan-size (artdag/plan pl-W 2))
  5)

(artdag-test
  "wide unlimited: single wave of four after leaf"
  (artdag/plan-width (artdag/plan pl-W 0))
  4)

; ---- incremental (dirty-only) plan ----

(artdag-test
  "dirty plan: schedules only the dirty closure"
  (artdag/plan-size (artdag/plan-dirty pl-D (list pl-b) 0))
  2)

(artdag-test
  "dirty plan: b then d"
  (artdag/plan-dirty pl-D (list pl-b) 0)
  (list (list pl-b) (list pl-d)))

(artdag-test
  "dirty plan: clean deps treated as satisfied"
  (first (artdag/plan-dirty pl-D (list pl-b) 0))
  (list pl-b))

(artdag-test
  "dirty plan: leaf change replans whole graph"
  (artdag/plan-size (artdag/plan-dirty pl-D (list pl-a) 0))
  4)

(artdag-test
  "dirty plan: sink change is a single batch"
  (artdag/plan-dirty pl-D (list pl-d) 0)
  (list (list pl-d)))
