;; lib/mod/tests/sla.sx — Ext 13: SLA sweep over pending lifecycle cases.

(define mod-sla-count 0)
(define mod-sla-pass 0)
(define mod-sla-fail 0)
(define mod-sla-failures (list))

(define
  mod-sla-test!
  (fn
    (name got expected)
    (begin
      (set! mod-sla-count (+ mod-sla-count 1))
      (if
        (= got expected)
        (set! mod-sla-pass (+ mod-sla-pass 1))
        (begin
          (set! mod-sla-fail (+ mod-sla-fail 1))
          (append!
            mod-sla-failures
            (str name "\n    expected: " expected "\n    got:      " got)))))))

;; ── pending-state? ──

(mod-sla-test! "open is pending" (mod/pending-state? "open") true)
(mod-sla-test! "triaged is pending" (mod/pending-state? "triaged") true)
(mod-sla-test! "appealed is pending" (mod/pending-state? "appealed") true)
(mod-sla-test! "decided is not pending" (mod/pending-state? "decided") false)
(mod-sla-test! "final is not pending" (mod/pending-state? "final") false)

;; build cases in known states
(define mod-sla-spam (mod/mk-report "r1" "u" "bob" "this is spam"))
(define mod-sla-spam-reports (list mod-sla-spam))
(define
  mod-sla-triaged
  (mod/case-triage
    (mod/mk-case mod-sla-spam)
    mod-sla-spam-reports
    mod/default-rules))
(define mod-sla-decided (mod/case-resolve mod-sla-triaged))
(define mod-sla-open (mod/mk-case (mod/mk-report "r2" "u" "eve" "hello")))

;; ── overdue? ──

(define mod-sla-tc-old (mod/mk-timed-case mod-sla-triaged 0))
(define mod-sla-tc-fresh (mod/mk-timed-case mod-sla-triaged 90))
(define mod-sla-tc-done (mod/mk-timed-case mod-sla-decided 0))

(mod-sla-test!
  "old triaged case is overdue"
  (mod/overdue? mod-sla-tc-old 100 50)
  true)
(mod-sla-test!
  "fresh triaged case not overdue"
  (mod/overdue? mod-sla-tc-fresh 100 50)
  false)
(mod-sla-test!
  "decided case never overdue"
  (mod/overdue? mod-sla-tc-done 100 50)
  false)
(mod-sla-test!
  "age computes elapsed ticks"
  (mod/age mod-sla-tc-old 100)
  100)
(mod-sla-test!
  "boundary: exactly at deadline not overdue"
  (mod/overdue?
    (mod/mk-timed-case mod-sla-triaged 50)
    100
    50)
  false)
(mod-sla-test!
  "boundary: one past deadline overdue"
  (mod/overdue?
    (mod/mk-timed-case mod-sla-triaged 49)
    100
    50)
  true)

;; ── sweep over a mixed queue ──

(define
  mod-sla-queue
  (list
    (mod/mk-timed-case mod-sla-triaged 0)
    (mod/mk-timed-case mod-sla-decided 0)
    (mod/mk-timed-case mod-sla-open 90)))      ;; r2, pending, age 10 → not

(mod-sla-test!
  "sweep finds only the overdue pending case"
  (mod/sla-sweep mod-sla-queue 100 50)
  (list "r1"))
(mod-sla-test!
  "overdue-count agrees"
  (mod/overdue-count mod-sla-queue 100 50)
  1)

;; tighten deadline so the young open case also breaches
(mod-sla-test!
  "tighter deadline catches the open case too"
  (mod/overdue-count mod-sla-queue 100 5)
  2)
(mod-sla-test!
  "empty queue → no breaches"
  (mod/sla-sweep (list) 100 50)
  (list))

(define mod-sla-tests-run! (fn () {:failures mod-sla-failures :total mod-sla-count :passed mod-sla-pass :failed mod-sla-fail}))
