from decimal import Decimal
from datetime import datetime, timezone, timedelta

from src.market.context import CoinMarketContext, MarketContextSnapshot
from src.risk.data_quality_gate import DataQualityGate


def _ctx(**overrides):
    base = dict(
        coin="WLD", rsi=Decimal("55"), sma_fast=Decimal("1.1"), sma_slow=Decimal("1.0"),
        atr=Decimal("0.05"), funding=Decimal("0"), volume=Decimal("1000000"), mid=Decimal("1.2"),
        spread_pct=Decimal("0.05"), timestamp=datetime.now(timezone.utc), reliability_score=Decimal("0.95"),
        stale_data=False, l2_available=True,
    )
    base.update(overrides)
    return CoinMarketContext(**base)


def test_data_quality_gate_blocks_stale_missing_l2_high_spread_and_api_degraded():
    gate = DataQualityGate(max_age_seconds=60, max_spread_pct=Decimal("0.20"))
    old = _ctx(timestamp=datetime.now(timezone.utc) - timedelta(minutes=3))
    assert gate.evaluate(old).allowed is False
    assert "stale_context" in gate.evaluate(old).reasons
    assert "missing_l2_book" in gate.evaluate(_ctx(l2_available=False)).reasons
    assert "spread_too_wide" in gate.evaluate(_ctx(spread_pct=Decimal("0.30"))).reasons
    assert "api_degraded" in gate.evaluate(_ctx(), degraded_mode_active=True).reasons


def test_market_snapshot_contains_core_and_research_universe():
    snap = MarketContextSnapshot.from_coin_contexts([_ctx(coin=c) for c in ["BTC", "ETH", "SOL", "LINK", "WLD", "SUI", "ENA", "BCH", "HYPE"]])
    assert snap.get("WLD").coin == "WLD"
    assert snap.get("SUI").coin == "SUI"
    assert set(["BTC", "ETH", "SOL", "LINK", "WLD", "SUI", "ENA", "BCH"]).issubset(snap.coins)
