"""Tests for HyperliquidClient."""

from __future__ import annotations

from decimal import Decimal

import pytest
from pytest_httpx import HTTPXMock

from cerbero_bite.clients._base import HttpToolClient
from cerbero_bite.clients._exceptions import McpDataAnomalyError
from cerbero_bite.clients.hyperliquid import (
    HOURLY_FUNDING_PERIODS_PER_YEAR,
    HyperliquidClient,
)


def _client() -> HyperliquidClient:
    http = HttpToolClient(
        service="hyperliquid",
        base_url="http://mcp-hyperliquid:9012",
        token="t",
        retry_max=1,
    )
    return HyperliquidClient(http)


@pytest.mark.asyncio
async def test_funding_rate_annualized(httpx_mock: HTTPXMock) -> None:
    httpx_mock.add_response(
        url="http://mcp-hyperliquid:9012/tools/get_funding_rate",
        json={"asset": "ETH", "current_funding_rate": 0.00005},
    )
    out = await _client().funding_rate_annualized("eth")
    assert out == Decimal("0.00005") * Decimal(HOURLY_FUNDING_PERIODS_PER_YEAR)


@pytest.mark.asyncio
async def test_funding_rate_anomaly_on_error_envelope(httpx_mock: HTTPXMock) -> None:
    httpx_mock.add_response(json={"error": "Asset XYZ not found"})
    with pytest.raises(McpDataAnomalyError, match="Asset XYZ"):
        await _client().funding_rate_annualized("XYZ")


@pytest.mark.asyncio
async def test_funding_rate_anomaly_when_rate_missing(httpx_mock: HTTPXMock) -> None:
    httpx_mock.add_response(json={"asset": "ETH"})
    with pytest.raises(McpDataAnomalyError, match="current_funding_rate"):
        await _client().funding_rate_annualized("ETH")


def test_hyperliquid_client_rejects_wrong_service() -> None:
    bad = HttpToolClient(
        service="macro", base_url="http://x:1", token="t", retry_max=1
    )
    with pytest.raises(ValueError, match="requires service 'hyperliquid'"):
        HyperliquidClient(bad)
