"""Tests for MCPGateway client entry point."""

from __future__ import annotations

from unittest.mock import AsyncMock, patch

import pytest

from mcpgateway_sdk.resources.auth import AuthResource
from mcpgateway_sdk.resources.cache import CacheResource
from mcpgateway_sdk.resources.sandboxes import SandboxesResource
from mcpgateway_sdk.resources.servers import ServersResource
from mcpgateway_sdk.resources.sessions import SessionsResource
from mcpgateway_sdk.resources.skills import SkillsResource
from mcpgateway_sdk.resources.tools import ToolsResource


class TestMCPGatewayInit:
    """MCPGateway constructor attaches all 7 resource attributes."""

    def test_has_servers_resource(self) -> None:
        from mcpgateway_sdk._client import MCPGateway

        gw = MCPGateway(api_key="test-key", url="http://localhost:8000")
        assert isinstance(gw.servers, ServersResource)

    def test_has_tools_resource(self) -> None:
        from mcpgateway_sdk._client import MCPGateway

        gw = MCPGateway(api_key="test-key", url="http://localhost:8000")
        assert isinstance(gw.tools, ToolsResource)

    def test_has_skills_resource(self) -> None:
        from mcpgateway_sdk._client import MCPGateway

        gw = MCPGateway(api_key="test-key", url="http://localhost:8000")
        assert isinstance(gw.skills, SkillsResource)

    def test_has_sessions_resource(self) -> None:
        from mcpgateway_sdk._client import MCPGateway

        gw = MCPGateway(api_key="test-key", url="http://localhost:8000")
        assert isinstance(gw.sessions, SessionsResource)

    def test_has_sandboxes_resource(self) -> None:
        from mcpgateway_sdk._client import MCPGateway

        gw = MCPGateway(api_key="test-key", url="http://localhost:8000")
        assert isinstance(gw.sandboxes, SandboxesResource)

    def test_has_auth_resource(self) -> None:
        from mcpgateway_sdk._client import MCPGateway

        gw = MCPGateway(api_key="test-key", url="http://localhost:8000")
        assert isinstance(gw.auth, AuthResource)

    def test_has_cache_resource(self) -> None:
        from mcpgateway_sdk._client import MCPGateway

        gw = MCPGateway(api_key="test-key", url="http://localhost:8000")
        assert isinstance(gw.cache, CacheResource)


class TestMCPGatewayProperties:
    """MCPGateway properties return correct values."""

    def test_mcp_url_returns_gateway_path(self) -> None:
        from mcpgateway_sdk._client import MCPGateway

        gw = MCPGateway(api_key="k", url="http://myhost:9999")
        assert gw.mcp_url == "http://myhost:9999/mcp/gateway"

    def test_mcp_url_strips_trailing_slash(self) -> None:
        from mcpgateway_sdk._client import MCPGateway

        gw = MCPGateway(api_key="k", url="http://myhost:9999/")
        assert gw.mcp_url == "http://myhost:9999/mcp/gateway"

    def test_auth_headers_returns_bearer_token(self) -> None:
        from mcpgateway_sdk._client import MCPGateway

        gw = MCPGateway(api_key="my-secret-key", url="http://localhost:8000")
        assert gw.auth_headers == {"Authorization": "Bearer my-secret-key"}


class TestMCPGatewayContextManager:
    """MCPGateway works as an async context manager."""

    async def test_aenter_returns_self(self) -> None:
        from mcpgateway_sdk._client import MCPGateway

        gw = MCPGateway(api_key="k", url="http://localhost:8000")
        result = await gw.__aenter__()
        assert result is gw
        await gw.close()

    async def test_async_with_calls_close(self) -> None:
        from mcpgateway_sdk._client import MCPGateway

        gw = MCPGateway(api_key="k", url="http://localhost:8000")
        with patch.object(gw, "close", new_callable=AsyncMock) as mock_close:
            async with gw:
                pass
            mock_close.assert_awaited_once()


class TestPackageExports:
    """Top-level package exports MCPGateway and all exceptions."""

    def test_import_mcpgateway_class(self) -> None:
        from mcpgateway_sdk import MCPGateway

        assert MCPGateway is not None

    def test_import_version(self) -> None:
        from mcpgateway_sdk import __version__

        assert isinstance(__version__, str)

    def test_import_gateway_error(self) -> None:
        from mcpgateway_sdk import GatewayError

        assert issubclass(GatewayError, Exception)

    def test_import_auth_error(self) -> None:
        from mcpgateway_sdk import AuthError

        assert issubclass(AuthError, Exception)

    def test_import_not_found_error(self) -> None:
        from mcpgateway_sdk import NotFoundError

        assert issubclass(NotFoundError, Exception)

    def test_import_conflict_error(self) -> None:
        from mcpgateway_sdk import ConflictError

        assert issubclass(ConflictError, Exception)

    def test_import_validation_error(self) -> None:
        from mcpgateway_sdk import ValidationError

        assert issubclass(ValidationError, Exception)

    def test_import_rate_limit_error(self) -> None:
        from mcpgateway_sdk import RateLimitError

        assert issubclass(RateLimitError, Exception)

    def test_import_forbidden_error(self) -> None:
        from mcpgateway_sdk import ForbiddenError

        assert issubclass(ForbiddenError, Exception)

    def test_all_exports_list(self) -> None:
        import mcpgateway_sdk

        expected = {
            "MCPGateway",
            "__version__",
            "AuthError",
            "ConflictError",
            "ForbiddenError",
            "GatewayError",
            "NotFoundError",
            "RateLimitError",
            "ValidationError",
        }
        assert set(mcpgateway_sdk.__all__) == expected
