"""GodotIQ MCP server — entry point and tool registration."""

from __future__ import annotations

import logging
import sys
from contextlib import asynccontextmanager
from pathlib import Path

from mcp.server.fastmcp import FastMCP

from godotiq import __version__
from godotiq.session import GodotIQSession, discover_project_root

# --- Startup logging to stderr so diagnostics are visible in MCP hosts ---
_startup_handler = logging.StreamHandler(sys.stderr)
_startup_handler.setFormatter(
    logging.Formatter("[godotiq] %(levelname)s: %(message)s")
)
logging.getLogger("godotiq").addHandler(_startup_handler)
logging.getLogger("godotiq").setLevel(logging.INFO)

logger = logging.getLogger(__name__)


@asynccontextmanager
async def godotiq_lifespan(server):
    """Initialize GodotIQ session on server startup."""
    project_root = discover_project_root()
    if project_root is not None:
        logger.info("Project root: %s", project_root)
        session = GodotIQSession(project_root)
        try:
            session.load()
        except Exception:
            logger.exception("Failed to load project at %s", project_root)
            session = None
        else:
            logger.info(
                "Session loaded: %s (%d scripts, %d scenes)",
                session._index.project_name,
                session._index.total_scripts,
                session._index.total_scenes,
            )
    else:
        session = None
        logger.warning("No Godot project found. Tools will return errors.")
    try:
        yield {"session": session}
    finally:
        from godotiq.bridge.session import close_bridge
        await close_bridge()


mcp = FastMCP(name="godotiq", lifespan=godotiq_lifespan)

# Fix __main__ double-import: when run via `python -m godotiq.server`,
# this module is loaded as __main__. Tool modules that do
# `from godotiq.server import mcp` would trigger a second import,
# creating a separate mcp instance. Register ourselves under the
# canonical name so all imports share the same mcp object.
sys.modules.setdefault("godotiq.server", sys.modules[__name__])


PROMPT_DIR = Path(__file__).resolve().parent / "prompts"


@mcp.prompt("godot-development")
async def godot_development_prompt() -> str:
    """GodotIQ development guide — tool workflows, conventions, best practices."""
    return (PROMPT_DIR / "godot_development.md").read_text(encoding="utf-8")


_cached_update_version: str | None = None
_update_checked: bool = False


def _is_newer_version(remote: str, local: str) -> bool:
    """Return True if remote version is strictly newer than local."""
    r = [int(x) for x in remote.split(".")]
    l = [int(x) for x in local.split(".")]  # noqa: E741
    max_len = max(len(r), len(l))
    for i in range(max_len):
        rv = r[i] if i < len(r) else 0
        lv = l[i] if i < len(l) else 0
        if rv > lv:
            return True
        if rv < lv:
            return False
    return False


async def _check_pypi_update() -> str | None:
    """Check PyPI for a newer version. Returns version string or None."""
    global _cached_update_version, _update_checked
    if _update_checked:
        return _cached_update_version
    _update_checked = True
    try:
        import httpx

        async with httpx.AsyncClient(timeout=10.0) as client:
            resp = await client.get("https://pypi.org/pypi/godotiq/json")
            if resp.status_code == 200:
                remote = resp.json()["info"]["version"]
                if _is_newer_version(remote, __version__):
                    _cached_update_version = remote
    except Exception:
        pass
    return _cached_update_version


@mcp.tool()
async def godotiq_ping(detail: str = "normal") -> dict:
    """Health check tool. Returns server status and version.

    Args:
        detail: Output verbosity — "brief" (summary), "normal" (default), or "full" (everything).
    """
    from godotiq.license import is_pro

    result = {
        "status": "ok",
        "version": __version__,
        "license": "pro" if is_pro() else "community",
    }
    update = await _check_pypi_update()
    if update:
        result["update_available"] = update
    return result


# Tool imports — each module registers tools on the mcp instance
from godotiq.tools import memory  # noqa: E402, F401
from godotiq.tools import code  # noqa: E402, F401
from godotiq.tools import spatial  # noqa: E402, F401
from godotiq.tools import assets  # noqa: E402, F401
from godotiq.tools import animation  # noqa: E402, F401
from godotiq.tools import bridge  # noqa: E402, F401
from godotiq.tools import flow  # noqa: E402, F401


def main() -> None:
    """Start the GodotIQ MCP server with stdio transport."""
    mcp.run(transport="stdio")


if __name__ == "__main__":
    main()
