# web/mcp_registrations.py
"""Read MCP server registrations from host config files mounted in /host."""

from __future__ import annotations

import json
import logging
from pathlib import Path
from typing import Any

logger = logging.getLogger(__name__)

HOST_DIR = Path("/host")


def _redact_env_keys(env: dict[str, Any] | None) -> list[str]:
    if not env or not isinstance(env, dict):
        return []
    return sorted(env.keys())


def _read_claude_registrations() -> list[dict[str, Any]]:
    """Read MCP registrations from /host/.claude.json."""
    path = HOST_DIR / ".claude.json"
    if not path.exists():
        return []
    try:
        data = json.loads(path.read_text(encoding="utf-8"))
    except Exception as e:
        logger.warning("claude_json_parse_failed: %s", e)
        return []
    out: list[dict[str, Any]] = []
    # Top-level mcpServers
    for name, cfg in (data.get("mcpServers") or {}).items():
        out.append(_normalize("Claude Code (global)", name, cfg))
    # Per-project mcpServers
    for project_path, project_cfg in (data.get("projects") or {}).items():
        for name, cfg in (project_cfg.get("mcpServers") or {}).items():
            out.append(_normalize(f"Claude Code ({project_path})", name, cfg))
    return out


def _read_paperclip_registrations() -> list[dict[str, Any]]:
    """Read MCP registrations from /host/.paperclip/instances/*/mcp.json."""
    base = HOST_DIR / ".paperclip" / "instances"
    if not base.exists():
        return []
    out: list[dict[str, Any]] = []
    for instance_dir in sorted(base.iterdir()):
        if not instance_dir.is_dir():
            continue
        mcp_json = instance_dir / "mcp.json"
        if not mcp_json.exists():
            continue
        try:
            data = json.loads(mcp_json.read_text(encoding="utf-8"))
        except Exception as e:
            logger.warning(
                "paperclip_mcp_json_parse_failed: %s %s",
                instance_dir.name, e,
            )
            continue
        if not isinstance(data, dict):
            logger.warning(
                "paperclip_mcp_json_unexpected_type: %s type=%s",
                instance_dir.name, type(data).__name__,
            )
            continue
        servers = data.get("mcpServers") or data
        if not isinstance(servers, dict):
            continue
        for name, cfg in servers.items():
            if not isinstance(cfg, dict):
                continue
            out.append(_normalize(f"Paperclip ({instance_dir.name})", name, cfg))
    return out


def _normalize(client: str, server_name: str, cfg: dict[str, Any]) -> dict[str, Any]:
    return {
        "client": client,
        "server_name": server_name,
        "command": cfg.get("command", ""),
        "args": cfg.get("args") or [],
        "cwd": cfg.get("cwd") or cfg.get("workingDirectory") or "",
        "env_keys": _redact_env_keys(cfg.get("env")),
        "transport": cfg.get("transport") or "stdio",
    }


def list_registrations() -> dict[str, Any]:
    """Return all MCP registrations + status."""
    if not HOST_DIR.exists():
        return {
            "registrations": [],
            "error": "host_path_unavailable",
            "message": "תיקיית /host לא mounted. ראה runbook להגדרת volumes ב-Coolify.",
        }
    registrations = (
        _read_claude_registrations() + _read_paperclip_registrations()
    )
    registrations.sort(key=lambda r: (r["client"], r["server_name"]))
    return {
        "registrations": registrations,
        "error": None,
    }
