from __future__ import annotations

import json
import logging
import os
from typing import Any

_log = logging.getLogger(__name__)


MCP_CONFIG_PATH = os.path.expanduser("~/.mugi/mcp_servers.json")


def load_mcp_config() -> dict[str, Any]:
    if not os.path.isfile(MCP_CONFIG_PATH):
        return {"mcpServers": {}}
    try:
        with open(MCP_CONFIG_PATH, "r", encoding="utf-8") as f:
            data = json.load(f)
        if isinstance(data, dict) and isinstance(data.get("mcpServers"), dict):
            return data
    except Exception:
        _log.warning(
            "Failed to load MCP config from %s; using empty mcpServers",
            MCP_CONFIG_PATH,
            exc_info=True,
        )
    return {"mcpServers": {}}


def iter_enabled_servers() -> list[tuple[str, dict[str, Any]]]:
    cfg = load_mcp_config()
    return iter_enabled_servers_from_config(cfg)


def iter_enabled_servers_from_config(cfg: dict[str, Any]) -> list[tuple[str, dict[str, Any]]]:
    servers = cfg.get("mcpServers") or {}
    out: list[tuple[str, dict[str, Any]]] = []
    for sid, raw in servers.items():
        if not isinstance(sid, str) or not isinstance(raw, dict):
            continue
        if raw.get("enabled", True) is False:
            continue
        out.append((sid, raw))
    return out


def sdk_installed() -> bool:
    try:
        import mcp  # noqa: F401
        return True
    except Exception:
        return False


def summarize_servers() -> list[dict[str, Any]]:
    cfg = load_mcp_config()
    servers = cfg.get("mcpServers")
    if not isinstance(servers, dict):
        return []
    out: list[dict[str, Any]] = []
    for sid, raw in servers.items():
        if not isinstance(sid, str) or not isinstance(raw, dict):
            continue
        is_http = bool(raw.get("url"))
        transport = "http" if is_http else "stdio"
        summary = str(raw.get("url") or "").strip() if is_http else str(raw.get("command") or "").strip()
        out.append(
            {
                "id": sid,
                "enabled": raw.get("enabled", True) is not False,
                "transport": transport,
                "summary": summary,
            }
        )
    return out


def validate_mcp_config_dict(obj: Any, *, max_servers: int = 64) -> str | None:
    if not isinstance(obj, dict):
        return "Root JSON must be an object."
    allowed_top = {"mcpServers", "$schema"}
    extra = [k for k in obj.keys() if k not in allowed_top]
    if extra:
        return f"Unknown top-level keys: {', '.join(sorted(extra))}"
    servers = obj.get("mcpServers")
    if not isinstance(servers, dict):
        return "mcpServers must be an object."
    if len(servers) > max_servers:
        return f"Too many MCP servers (max {max_servers})."
    for sid, raw in servers.items():
        if not isinstance(sid, str) or not sid.strip():
            return "Server IDs must be non-empty strings."
        if not isinstance(raw, dict):
            return f"Server '{sid}' must be an object."
    return None
