"""
Tests for the failover manager.
"""

from app.core.failover import FailoverManager


def test_default_returns_primary():
    """Without any events, primary is the recommended provider."""
    fm = FailoverManager(primary="binance", backups=["bybit"])
    assert fm.get_best_provider("BTCUSDT") == "binance"


def test_gaps_cause_switch():
    """Enough gaps should cause a switch to backup."""
    fm = FailoverManager(
        primary="binance",
        backups=["bybit"],
        switch_threshold=0.3,
    )

    # Record some events for bybit so it has health
    for _ in range(10):
        fm.record_event("bybit", "BTCUSDT")

    # Degrade binance heavily (5 gaps = -1.0)
    for _ in range(5):
        fm.record_gap("binance", "BTCUSDT")

    best = fm.get_best_provider("BTCUSDT")
    assert best == "bybit"


def test_recovery_returns_to_primary():
    """When primary recovers, switch back from backup."""
    fm = FailoverManager(
        primary="binance",
        backups=["bybit"],
        switch_threshold=0.3,
        recovery_threshold=0.7,
    )

    # Degrade primary and switch to backup
    for _ in range(10):
        fm.record_event("bybit", "BTCUSDT")
    for _ in range(5):
        fm.record_gap("binance", "BTCUSDT")

    assert fm.get_best_provider("BTCUSDT") == "bybit"

    # Now primary recovers (many events increase score)
    for _ in range(100):
        fm.record_event("binance", "BTCUSDT")

    assert fm.get_best_provider("BTCUSDT") == "binance"


def test_status_report():
    """Status report includes all provider/symbol pairs."""
    fm = FailoverManager(primary="binance", backups=["bybit"])

    fm.record_event("binance", "BTCUSDT")
    fm.record_event("bybit", "BTCUSDT")
    fm.record_gap("binance", "ETHUSDT")

    status = fm.get_status()
    assert "binance/BTCUSDT" in status
    assert "bybit/BTCUSDT" in status
    assert "binance/ETHUSDT" in status
    assert status["binance/BTCUSDT"]["events"] == 1
    assert status["binance/ETHUSDT"]["gaps"] == 1


def test_no_backup_stays_on_primary():
    """Without backups, always returns primary even when degraded."""
    fm = FailoverManager(primary="binance", backups=[])

    for _ in range(5):
        fm.record_gap("binance", "BTCUSDT")

    # No alternative, stays on binance
    assert fm.get_best_provider("BTCUSDT") == "binance"
