;; lib/mod/tests/batch.sx — Ext 11: batch triage + corpus analytics.

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

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

;; corpus: 2 spam, 1 abuse, 2 clean — distinct subjects so the count rule stays quiet
(define
  mod-b-corpus
  (list
    (mod/mk-report "r1" "u" "s1" "this is spam")
    (mod/mk-report "r2" "u" "s2" "buy now offer")
    (mod/mk-report "r3" "u" "s3" "harassment here")
    (mod/mk-report "r4" "u" "s4" "a fine post")
    (mod/mk-report "r5" "u" "s5" "thanks for sharing")))

(define mod-b-decisions (mod/decide-batch mod-b-corpus mod/default-rules))

;; ── decide-batch ──

(mod-b-test! "one decision per report" (len mod-b-decisions) 5)
(mod-b-test!
  "first decision is hide"
  (get (first mod-b-decisions) :action)
  "hide")

;; ── action histogram ──

(define mod-b-hist (mod/action-histogram mod-b-decisions))
(mod-b-test! "histogram hide count" (get mod-b-hist :hide) 2)
(mod-b-test! "histogram remove count" (get mod-b-hist :remove) 1)
(mod-b-test! "histogram keep count" (get mod-b-hist :keep) 2)
(mod-b-test! "histogram escalate count" (get mod-b-hist :escalate) 0)
(mod-b-test! "histogram ban count" (get mod-b-hist :ban) 0)
(mod-b-test!
  "histogram totals match corpus"
  (+
    (+ (get mod-b-hist :hide) (get mod-b-hist :remove))
    (+
      (get mod-b-hist :keep)
      (+ (get mod-b-hist :escalate) (get mod-b-hist :ban))))
  5)

;; ── rule coverage (empirical) ──

(define mod-b-cov (mod/rule-coverage mod-b-corpus mod/default-rules))
(mod-b-test! "coverage has one row per rule" (len mod-b-cov) 6)
(mod-b-test!
  "spam-hide fired twice"
  (mod/rule-fire-count mod-b-decisions "spam-hide")
  2)
(mod-b-test!
  "abuse-remove fired once"
  (mod/rule-fire-count mod-b-decisions "abuse-remove")
  1)
(mod-b-test!
  "default-keep fired twice"
  (mod/rule-fire-count mod-b-decisions "default-keep")
  2)

;; ── never-fired: rules not exercised by this corpus ──

(define mod-b-never (mod/never-fired mod-b-corpus mod/default-rules))
(mod-b-test!
  "exonerated-keep never fired"
  (mod/member? "exonerated-keep" mod-b-never)
  true)
(mod-b-test!
  "reviewer-remove never fired"
  (mod/member? "reviewer-remove" mod-b-never)
  true)
(mod-b-test!
  "repeated-escalate never fired"
  (mod/member? "repeated-escalate" mod-b-never)
  true)
(mod-b-test!
  "spam-hide DID fire (not in never-fired)"
  (mod/member? "spam-hide" mod-b-never)
  false)
(mod-b-test!
  "three rules never fired on this corpus"
  (len mod-b-never)
  3)

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