"""End-to-end test for ``cerbero-bite ping``.

The CLI uses the production code paths, so we set up an HTTP mock that
matches every URL Bite is going to hit and assert the rendered output
contains the expected statuses.
"""

from __future__ import annotations

import pytest
from click.testing import CliRunner
from pytest_httpx import HTTPXMock

from cerbero_bite.cli import main as cli_main


def test_ping_reports_each_service(httpx_mock: HTTPXMock) -> None:
    httpx_mock.add_response(
        url="http://mcp-deribit:9011/tools/environment_info",
        json={
            "exchange": "deribit",
            "environment": "testnet",
            "source": "env",
            "env_value": "true",
            "base_url": "https://test.deribit.com/api/v2",
            "max_leverage": 3,
        },
    )
    httpx_mock.add_response(
        url="http://mcp-hyperliquid:9012/tools/get_funding_rate",
        json={"asset": "ETH", "current_funding_rate": 0.0001},
    )
    httpx_mock.add_response(
        url="http://mcp-macro:9013/tools/get_macro_calendar",
        json={"events": []},
    )
    httpx_mock.add_response(
        url="http://mcp-sentiment:9014/tools/get_cross_exchange_funding",
        json={"snapshot": {"ETH": {"binance": 0.0001}}},
    )

    result = CliRunner().invoke(
        cli_main, ["ping", "--token", "super-secret", "--timeout", "1.0"]
    )
    assert result.exit_code == 0, result.output
    assert "deribit" in result.output
    assert "hyperliquid" in result.output
    assert "macro" in result.output
    assert "sentiment" in result.output
    # Telegram and Portfolio are no longer MCP services and are not
    # listed by the ping command.
    assert "portfolio" not in result.output
    assert "OK" in result.output


def test_ping_reports_failure_when_service_unreachable(
    httpx_mock: HTTPXMock,
) -> None:
    httpx_mock.add_response(
        url="http://mcp-deribit:9011/tools/environment_info",
        status_code=500,
        text="boom",
    )
    # Provide successful stubs for the others to keep the call small.
    httpx_mock.add_response(
        url="http://mcp-hyperliquid:9012/tools/get_funding_rate",
        json={"asset": "ETH", "current_funding_rate": 0.0001},
    )
    httpx_mock.add_response(
        url="http://mcp-macro:9013/tools/get_macro_calendar",
        json={"events": []},
    )
    httpx_mock.add_response(
        url="http://mcp-sentiment:9014/tools/get_cross_exchange_funding",
        json={"snapshot": {"ETH": {"binance": 0.0001}}},
    )

    result = CliRunner().invoke(
        cli_main, ["ping", "--token", "super-secret", "--timeout", "1.0"]
    )
    assert result.exit_code == 0
    assert "FAIL" in result.output


def test_ping_token_missing_exits_nonzero(
    monkeypatch: pytest.MonkeyPatch,
) -> None:
    # Ensure no env var leaks into the CLI invocation.
    monkeypatch.delenv("CERBERO_BITE_MCP_TOKEN", raising=False)
    result = CliRunner().invoke(cli_main, ["ping"])
    assert result.exit_code == 1
    assert "token error" in result.output
