"""MCPGateway client -- main entry point for the SDK."""

from __future__ import annotations

import logging
import warnings
from typing import Any

import mcpgateway_sdk
from mcpgateway_sdk._config import SDKConfig
from mcpgateway_sdk._exceptions import GatewayError
from mcpgateway_sdk._http import HTTPClient
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

logger = logging.getLogger(__name__)


def _parse_major_minor(version: str) -> tuple[int, int]:
    """Extract (major, minor) from a version string like '0.16.0'."""
    parts = version.split(".")
    return int(parts[0]), int(parts[1]) if len(parts) > 1 else 0


class MCPGateway:
    """Async client for the MCPGateway REST API.

    Usage::

        async with MCPGateway(api_key="sk-...", url="http://localhost:8000") as gw:
            tools = await gw.tools.search("weather")
            result = await gw.tools.execute(
                "get_weather", {"city": "NYC"}, server_name="weather"
            )
    """

    def __init__(
        self,
        api_key: str | None = None,
        url: str | None = None,
        timeout: float = 30.0,
        *,
        check_version: bool = True,
    ) -> None:
        self._config = SDKConfig(api_key=api_key, url=url, timeout=timeout)
        self._http = HTTPClient(self._config)
        self._check_version = check_version
        self._version_checked = False

        self.servers = ServersResource(self._http)
        self.tools = ToolsResource(self._http)
        self.skills = SkillsResource(self._http)
        self.sessions = SessionsResource(self._http)
        self.sandboxes = SandboxesResource(self._http)
        self.auth = AuthResource(self._http)
        self.cache = CacheResource(self._http)

    async def check_version(self) -> None:
        """Check SDK version against the server and warn if mismatched.

        Called automatically when using the async context manager
        (``async with MCPGateway() as gw:``) and ``check_version=True``.
        Compares major.minor — patch differences are ignored.
        """
        if self._version_checked or not self._check_version:
            return
        self._version_checked = True

        try:
            health: dict[str, Any] = await self._http.request("GET", "/health")
            server_version = health.get("version", "")
            sdk_version = mcpgateway_sdk.__version__

            if not server_version or sdk_version == "0.0.0-dev":
                return

            server_mm = _parse_major_minor(server_version)
            sdk_mm = _parse_major_minor(sdk_version)

            if server_mm != sdk_mm:
                msg = (
                    f"SDK version {sdk_version} does not match server version "
                    f"{server_version}. Update with: pip install --upgrade mcpgateway-sdk"
                )
                warnings.warn(msg, UserWarning, stacklevel=2)
                logger.warning(msg)
        except GatewayError:
            pass  # Don't fail on version check — it's advisory

    @property
    def mcp_url(self) -> str:
        """Full URL for the MCP gateway SSE endpoint."""
        return f"{self._config.url}/mcp/gateway"

    @property
    def auth_headers(self) -> dict[str, str]:
        """Headers needed to authenticate MCP connections."""
        return {"Authorization": f"Bearer {self._config.api_key}"}

    async def close(self) -> None:
        """Close the underlying HTTP client."""
        await self._http.close()

    async def __aenter__(self) -> MCPGateway:
        await self.check_version()
        return self

    async def __aexit__(self, *args: Any) -> None:
        await self.close()
