// test_convergence.el — convergence strategies + failure threshold / abort.

fn assert_true(label: String, cond: Bool, fails: Int) -> Int {
    if cond { print("  ok   " + label); return fails }
    print("  FAIL " + label); return fails + 1
}

fn main() -> Int {
    let fails = 0
    let refs: String = "[]"

    // ── vote: classify 5 inputs; 3 "long" (>4 chars) vs 2 "short" -> winner long ──
    let inputs: String = "[\"alpha\",\"bravo\",\"hi\",\"charlie\",\"ok\"]"
    let cfg_v: String = "{\"concurrency\":\"3\",\"strategy\":\"vote\",\"min_success_ratio\":\"1.0\"}"
    let rv: String = swarm_run("classify", refs, inputs, cfg_v)
    let merged_v: String = json_get_raw(rv, "merged")
    let winner: String = json_get_string(merged_v, "winner")
    let votes: Int = str_to_int(json_get_string(merged_v, "votes"))
    let fails = assert_true("vote winner = long", str_eq(winner, "long"), fails)
    let fails = assert_true("vote count = 3", votes == 3, fails)

    // ── merge: outputs joined ──
    let cfg_m: String = "{\"concurrency\":\"2\",\"strategy\":\"merge\",\"min_success_ratio\":\"1.0\"}"
    let rm: String = swarm_run("analyze_item", refs, "[\"a\",\"b\",\"c\"]", cfg_m)
    let merged_m: String = json_get_raw(rm, "merged")
    let joined: String = json_get_string(merged_m, "merged")
    let fails = assert_true("merge produced a joined string", str_contains(joined, "|"), fails)

    // ── reduce: count accumulates ──
    let cfg_r: String = "{\"concurrency\":\"4\",\"strategy\":\"reduce\",\"min_success_ratio\":\"1.0\"}"
    let rr: String = swarm_run("analyze_item", refs, "[\"a\",\"b\",\"c\",\"d\"]", cfg_r)
    let merged_r: String = json_get_raw(rr, "merged")
    let rcount: Int = str_to_int(json_get_string(merged_r, "count"))
    let fails = assert_true("reduce count = 4", rcount == 4, fails)

    // ── failure threshold: 2 of 5 fail (x-prefixed); ratio 3/5=0.6 < 0.8 -> aborted ──
    let fin: String = "[\"a\",\"xb\",\"c\",\"xd\",\"e\"]"
    let cfg_f: String = "{\"concurrency\":\"5\",\"strategy\":\"collect\",\"min_success_ratio\":\"0.8\"}"
    let rf: String = swarm_run("faildemo", refs, fin, cfg_f)
    let fstatus: String = json_get_string(rf, "status")
    let fails = assert_true("swarm aborted below min_success_ratio (0.6<0.8)", str_eq(fstatus, "aborted"), fails)
    let corr_f: String = json_get_string(rf, "corr_id")
    let failed_n: Int = worktrack_count_kind(corr_f, "worker.failed")
    let aborted_n: Int = worktrack_count_kind(corr_f, "swarm.aborted")
    let fails = assert_true("tracked 2 worker.failed", failed_n == 2, fails)
    let fails = assert_true("tracked swarm.aborted", aborted_n == 1, fails)

    // ── same failures tolerated when min_success_ratio=0.5 (0.6>=0.5) -> completed ──
    let cfg_ok: String = "{\"concurrency\":\"5\",\"strategy\":\"collect\",\"min_success_ratio\":\"0.5\"}"
    let rok: String = swarm_run("faildemo", refs, fin, cfg_ok)
    let fails = assert_true("swarm completes when failures within tolerance", str_eq(json_get_string(rok, "status"), "completed"), fails)

    if fails == 0 { print("PASS test_convergence"); return 0 }
    print("FAIL test_convergence (" + int_to_str(fails) + ")"); return 1
}
