"""Crypto fetch: offline (injected GET) — universe selection, npz keys/shape, <200-bar skip, refresh."""
from __future__ import annotations

import numpy as np

from fxhnt.adapters.data.crypto_fetch import fetch_crypto_pit


def _fake_get_factory(n_bars: int):
    """Return a `get(url)` that serves canned Binance fapi JSON for any symbol."""
    def get(url: str):
        if "exchangeInfo" in url:
            return {"symbols": [
                {"symbol": "AAAUSDT", "contractType": "PERPETUAL", "quoteAsset": "USDT", "status": "TRADING"},
                {"symbol": "BBBUSDT", "contractType": "PERPETUAL", "quoteAsset": "USDT", "status": "TRADING"},
            ]}
        if "ticker/24hr" in url:
            return [{"symbol": "AAAUSDT", "quoteVolume": "9999"},
                    {"symbol": "BBBUSDT", "quoteVolume": "10"}]
        if "klines" in url:
            # n_bars daily klines: [openTime, o,h,l, close, vol, closeTime, quoteVol, ...]
            day_ms = 86_400_000
            return [[i * day_ms, "1", "1", "1", str(100 + i), "1", i * day_ms + 1, "1000", 0, 0, 0, 0]
                    for i in range(n_bars)]
        if "fundingRate" in url:
            return []
        return None
    return get


def test_writes_npz_with_day_and_close(tmp_path) -> None:
    n, total = fetch_crypto_pit(str(tmp_path), top_n=2, get=_fake_get_factory(300), sleep=lambda s: None, dead=[])
    assert n == 2 and total == 2
    z = np.load(tmp_path / "crypto_pit" / "AAAUSDT.npz")
    assert "day" in z and "close" in z
    assert len(z["day"]) == 300 and z["close"][0] == 100.0
    assert len(z["funding"]) == len(z["day"])  # funding is day-aligned


def test_skips_symbols_with_too_few_bars(tmp_path) -> None:
    n, total = fetch_crypto_pit(str(tmp_path), top_n=2, get=_fake_get_factory(50), sleep=lambda s: None, dead=[])
    assert n == 0 and total == 2          # <200 bars -> skipped


def test_refresh_overwrites_existing(tmp_path) -> None:
    fetch_crypto_pit(str(tmp_path), top_n=1, get=_fake_get_factory(300), sleep=lambda s: None, dead=[])
    # second run with longer series must overwrite (refresh), not skip
    fetch_crypto_pit(str(tmp_path), top_n=1, get=_fake_get_factory(400), sleep=lambda s: None, dead=[])
    z = np.load(tmp_path / "crypto_pit" / "AAAUSDT.npz")
    assert len(z["day"]) == 400
