from bubblecam import reboot_guard


def test_read_count_zero_when_no_counter_file(sim_env):
    assert reboot_guard.read_count() == 0


def test_increment_persists_and_returns_new_count(sim_env):
    assert reboot_guard.increment() == 1
    assert reboot_guard.increment() == 2
    assert reboot_guard.read_count() == 2


def test_reset_clears_counter(sim_env):
    reboot_guard.increment()
    reboot_guard.increment()
    reboot_guard.reset()
    assert reboot_guard.read_count() == 0


def test_reset_when_no_counter_file_is_a_no_op(sim_env):
    reboot_guard.reset()  # must not raise
    assert reboot_guard.read_count() == 0


def test_read_count_zero_when_storage_hangs(sim_env, monkeypatch):
    """A wedged SD card must not deadlock the watchdog's escalation: the
    counter reads as 0 ("attempts remaining") so the reboot still happens.
    This is the failure that left a real soak hung for 8.5 hours."""
    import time

    monkeypatch.setattr(reboot_guard, "_read_count_blocking", lambda: time.sleep(30))
    monkeypatch.setattr(reboot_guard.bounded_io, "DEFAULT_TIMEOUT_SECONDS", 0.1)
    started = time.monotonic()
    assert reboot_guard.read_count() == 0
    assert time.monotonic() - started < 3.0


def test_exhausted_false_when_storage_hangs(sim_env, monkeypatch):
    import time

    monkeypatch.setattr(reboot_guard, "_read_count_blocking", lambda: time.sleep(30))
    monkeypatch.setattr(reboot_guard.bounded_io, "DEFAULT_TIMEOUT_SECONDS", 0.1)
    # Fail toward rebooting -- never toward "give up and hang".
    assert reboot_guard.exhausted(3) is False


def test_increment_still_returns_a_count_when_write_hangs(sim_env, monkeypatch):
    import time

    monkeypatch.setattr(reboot_guard, "_increment_blocking", lambda: time.sleep(30))
    monkeypatch.setattr(reboot_guard.bounded_io, "DEFAULT_TIMEOUT_SECONDS", 0.1)
    assert reboot_guard.increment() >= 1


def test_exhausted(sim_env):
    assert reboot_guard.exhausted(3) is False
    reboot_guard.increment()
    reboot_guard.increment()
    assert reboot_guard.exhausted(3) is False
    reboot_guard.increment()
    assert reboot_guard.exhausted(3) is True
