from src.hyperliquid.api_health import ApiHealthMonitor, RequestBudget, RetryPolicy


def test_api_health_records_429_no_route_stale_and_degraded_mode():
    h = ApiHealthMonitor(max_stale_context_count=1)
    h.record_error(Exception("429 Too Many Requests"))
    h.record_error(OSError("No route to host"))
    h.record_ws_reconnect()
    h.record_stale_context()
    assert h.report()["api_429_count"] == 1
    assert h.report()["no_route_count"] == 1
    assert h.report()["ws_reconnect_count"] == 1
    assert h.report()["stale_context_count"] == 1
    assert h.degraded_mode_active is True


def test_request_budget_blocks_aggressive_polling():
    b = RequestBudget(max_requests=2, window_seconds=60)
    assert b.allow(now=1000) is True
    assert b.allow(now=1001) is True
    assert b.allow(now=1002) is False
    assert b.allow(now=1061) is True


def test_retry_policy_exponential_backoff_sequence():
    p = RetryPolicy(base_delay=0.5, max_delay=10, jitter=0)
    assert [p.delay_for_attempt(i) for i in range(4)] == [0.5, 1.0, 2.0, 4.0]
