"""Tests for the MCP endpoint, token and bot-tag resolver."""

from __future__ import annotations

import pytest

from cerbero_bite.config.mcp_endpoints import (
    DEFAULT_BOT_TAG,
    DEFAULT_ENDPOINTS,
    MCP_SERVICES,
    load_bot_tag,
    load_endpoints,
    load_token,
)


def test_defaults_match_known_docker_dns() -> None:
    assert DEFAULT_ENDPOINTS["deribit"] == "http://mcp-deribit:9011"
    assert DEFAULT_ENDPOINTS["sentiment"] == "http://mcp-sentiment:9014"


def test_load_endpoints_uses_defaults_when_env_empty() -> None:
    endpoints = load_endpoints(env={})
    for name, url in DEFAULT_ENDPOINTS.items():
        assert endpoints.for_service(name) == url


def test_per_service_env_var_override() -> None:
    endpoints = load_endpoints(
        env={"CERBERO_BITE_MCP_DERIBIT_URL": "http://localhost:9911"}
    )
    assert endpoints.deribit == "http://localhost:9911"
    assert endpoints.macro == DEFAULT_ENDPOINTS["macro"]


def test_per_service_env_var_strips_trailing_slash() -> None:
    endpoints = load_endpoints(
        env={"CERBERO_BITE_MCP_DERIBIT_URL": "http://localhost:9911///"}
    )
    assert endpoints.deribit == "http://localhost:9911"


def test_for_service_unknown_raises_key_error() -> None:
    endpoints = load_endpoints(env={})
    with pytest.raises(KeyError, match="unknown MCP service"):
        endpoints.for_service("nope")


def test_load_token_uses_explicit_value() -> None:
    assert load_token(value="abcdef") == "abcdef"


def test_load_token_strips_whitespace_in_explicit_value() -> None:
    assert load_token(value="  abcdef\n") == "abcdef"


def test_load_token_uses_env_var() -> None:
    token = load_token(env={"CERBERO_BITE_MCP_TOKEN": "xyz"})
    assert token == "xyz"


def test_load_token_strips_whitespace_in_env_var() -> None:
    token = load_token(env={"CERBERO_BITE_MCP_TOKEN": "  xyz\n"})
    assert token == "xyz"


def test_load_token_raises_when_missing() -> None:
    with pytest.raises(ValueError, match="CERBERO_BITE_MCP_TOKEN"):
        load_token(env={})


def test_load_token_raises_when_empty() -> None:
    with pytest.raises(ValueError, match="CERBERO_BITE_MCP_TOKEN"):
        load_token(env={"CERBERO_BITE_MCP_TOKEN": "   "})


def test_load_token_raises_when_explicit_value_blank() -> None:
    with pytest.raises(ValueError, match="empty"):
        load_token(value="   ")


def test_load_bot_tag_default_when_unset() -> None:
    assert load_bot_tag(env={}) == DEFAULT_BOT_TAG


def test_load_bot_tag_explicit_value_overrides_env() -> None:
    tag = load_bot_tag(value="BOT__CUSTOM", env={"CERBERO_BITE_MCP_BOT_TAG": "x"})
    assert tag == "BOT__CUSTOM"


def test_load_bot_tag_uses_env_when_set() -> None:
    tag = load_bot_tag(env={"CERBERO_BITE_MCP_BOT_TAG": "BOT__SHADOW"})
    assert tag == "BOT__SHADOW"


def test_load_bot_tag_strips_whitespace() -> None:
    tag = load_bot_tag(env={"CERBERO_BITE_MCP_BOT_TAG": "  BOT__X\n"})
    assert tag == "BOT__X"


def test_load_bot_tag_falls_back_to_default_when_blank_env() -> None:
    tag = load_bot_tag(env={"CERBERO_BITE_MCP_BOT_TAG": "   "})
    assert tag == DEFAULT_BOT_TAG


def test_load_bot_tag_rejects_too_long() -> None:
    with pytest.raises(ValueError, match="exceeds 64"):
        load_bot_tag(value="x" * 65)


def test_mcp_services_table_is_complete() -> None:
    # Telegram and Portfolio are now in-process and must NOT be listed
    # as shared MCP services.
    expected = {"deribit", "hyperliquid", "macro", "sentiment"}
    assert set(MCP_SERVICES) == expected
