"""TS-25 — quarantine: tracked on first fail, QUARANTINED at 3-of-5 fails,
evicted after 3 consecutive passes; state persists atomically.

`is_quarantined()` returns True once a test is *tracked* (first failure); the
actual quarantine flag is the entry's `quarantined_at` (set at the 3-fail
threshold). This pins both.
"""

from __future__ import annotations

from mgf.test_supervisor.quarantine import QuarantineStore
from mgf.test_supervisor.records import now_iso

_TID = "tests/unit/test_x.py::test_flaky"


def test_quarantine_threshold_and_eviction(tmp_path) -> None:
    store = QuarantineStore(tmp_path / "quarantine.json")

    # First failure: tracked (watched) but NOT yet quarantined. These two asserts used to
    # contradict each other — `is_quarantined()` True while `quarantined_at == ""` — which was
    # the bug itself: a single failure reported as quarantined, so the next run skipped a
    # genuinely broken test and went green. Tracked is not quarantined.
    store.update_outcome(_TID, "failed", "boom", now_iso())
    assert not store.is_quarantined(_TID)  # tracked, but not quarantined
    assert store.all()[_TID].quarantined_at == ""  # not yet quarantined

    # A pass proves it's flaky (not just broken); with 3 fails in the window → quarantined.
    # (entry already exists from the first failure above, so this pass is recorded)
    store.update_outcome(_TID, "passed", None, now_iso())
    store.update_outcome(_TID, "failed", "boom", now_iso())
    store.update_outcome(_TID, "failed", "boom", now_iso())
    assert store.all()[_TID].quarantined_at != ""

    # Two passes: still quarantined (needs 3 consecutive).
    store.update_outcome(_TID, "passed", None, now_iso())
    store.update_outcome(_TID, "passed", None, now_iso())
    assert store.is_quarantined(_TID)

    # Third consecutive pass → evicted entirely.
    store.update_outcome(_TID, "passed", None, now_iso())
    assert not store.is_quarantined(_TID)


def test_quarantine_persists_atomically(tmp_path) -> None:
    p = tmp_path / "quarantine.json"
    s1 = QuarantineStore(p)
    s1.update_outcome(_TID, "failed", "boom", now_iso())
    s1.update_outcome(_TID, "passed", None, now_iso())  # a pass -> flaky, not broken
    s1.update_outcome(_TID, "failed", "boom", now_iso())
    s1.update_outcome(_TID, "failed", "boom", now_iso())
    assert s1.all()[_TID].quarantined_at != ""
    s1.save()  # explicit persist (update_outcome accumulates in-memory)
    # A fresh store loading the same file sees the quarantine (atomic persistence).
    assert QuarantineStore(p).all()[_TID].quarantined_at != ""
