"""币安符号解析与中性到期工具测试。"""

from app.exchange.binance.parse import parse_option_symbol, rows_to_option_contracts
from app.exchange.expiry import expiry_ms_from_ymd, ymd_from_expiry_ms
from app.exchange.runtime import normalize_exchange_name


def test_binance_parse_option_symbol() -> None:
    y, stk, side = parse_option_symbol("ETH-250726-1860-C")
    assert y == "250726"
    assert stk == 1860.0
    assert side == "C"
    y2, _, side2 = parse_option_symbol("ETH-250726-1860-P")
    assert y2 == "250726" and side2 == "P"
    assert parse_option_symbol("ETHUSDT")[0] is None


def test_binance_rows_to_contracts() -> None:
    rows = [
        {
            "symbol": "ETH-250726-1860-C",
            "status": "TRADING",
            "strikePrice": "1860",
            "side": "CALL",
            "expiryDate": expiry_ms_from_ymd("250726"),
            "unit": "1",
            "underlying": "ETHUSDT",
        },
        {
            "symbol": "ETH-250726-1860-P",
            "status": "TRADING",
            "strikePrice": "1860",
            "side": "PUT",
            "expiryDate": expiry_ms_from_ymd("250726"),
            "unit": 1,
            "underlying": "ETHUSDT",
        },
    ]
    out = rows_to_option_contracts(rows)
    assert len(out) == 2
    assert out[0]["expiry_ymd"] == "250726"
    assert out[0]["ct_mult"] == 1.0
    assert out[0]["side"] in ("C", "P")


def test_expiry_ms_roundtrip() -> None:
    ms = expiry_ms_from_ymd("250726")
    assert ymd_from_expiry_ms(ms) == "250726"
    # UTC 08:00
    from datetime import datetime, timezone

    dt = datetime.fromtimestamp(ms / 1000, tz=timezone.utc)
    assert dt.hour == 8 and dt.minute == 0


def test_normalize_exchange() -> None:
    assert normalize_exchange_name("BN") == "binance"
    assert normalize_exchange_name("okx") == "okx"
    assert normalize_exchange_name(None) == "okx"


def test_binance_maps_okx_family_name() -> None:
    """误传 OKX family 时不应按 startswith(ETH) 乱匹配，应映射到 ETHUSDT。"""
    from app.exchange.binance.rest import BinanceRestClient

    cli = BinanceRestClient.__new__(BinanceRestClient)
    cli._exchange_info = {
        "optionSymbols": [
            {
                "symbol": "ETH-260726-1860-C",
                "underlying": "ETHUSDT",
                "status": "TRADING",
                "strikePrice": "1860",
                "side": "CALL",
                "expiryDate": 1785052800000,
                "unit": "1",
            },
            {
                "symbol": "BTC-260726-100000-C",
                "underlying": "BTCUSDT",
                "status": "TRADING",
                "strikePrice": "100000",
                "side": "CALL",
                "expiryDate": 1785052800000,
                "unit": "1",
            },
        ]
    }
    rows = BinanceRestClient.fetch_option_instruments(cli, "ETH-USD_UM")
    assert len(rows) == 1
    assert rows[0]["symbol"] == "ETH-260726-1860-C"
