# -*- coding: utf-8 -*-
"""Validate .mcp.json structure against expected schema."""
from typing import Any, Dict, List


# Schema: what a valid .mcp.json looks like
VALID_TOP_KEYS = {"mcpServers"}
VALID_SERVER_KEYS = {"command", "args", "env", "type", "url", "cwd", "disabled"}
VALID_TRANSPORT_TYPES = {"stdio", "http", "sse"}


def validate_config(config: Dict[str, Any]) -> List[str]:
    """Validate config and return list of error strings. Empty = valid."""
    errors = []

    if not isinstance(config, dict):
        return ["Config must be a JSON object"]

    # Check top-level keys
    if "mcpServers" not in config:
        errors.append("Missing required key: 'mcpServers'")
        return errors

    if not isinstance(config["mcpServers"], dict):
        errors.append("'mcpServers' must be an object")
        return errors

    unknown_top = set(config.keys()) - VALID_TOP_KEYS
    for key in sorted(unknown_top):
        errors.append(f"Unknown top-level key: '{key}'")

    # Validate each server
    for name, server in config["mcpServers"].items():
        prefix = f"Server '{name}'"

        if not isinstance(server, dict):
            errors.append(f"{prefix}: must be an object")
            continue

        unknown_keys = set(server.keys()) - VALID_SERVER_KEYS
        for key in sorted(unknown_keys):
            errors.append(f"{prefix}: unknown key '{key}'")

        # Must have command (stdio) or url (http)
        has_command = "command" in server
        has_url = "url" in server
        if not has_command and not has_url:
            errors.append(f"{prefix}: must have 'command' (stdio) or 'url' (http)")

        if has_command and not isinstance(server["command"], str):
            errors.append(f"{prefix}: 'command' must be a string")

        if "args" in server:
            if not isinstance(server["args"], list):
                errors.append(f"{prefix}: 'args' must be an array")
            elif not all(isinstance(a, str) for a in server["args"]):
                errors.append(f"{prefix}: all 'args' must be strings")

        if "env" in server:
            if not isinstance(server["env"], dict):
                errors.append(f"{prefix}: 'env' must be an object")
            elif not all(isinstance(v, str) for v in server["env"].values()):
                errors.append(f"{prefix}: all 'env' values must be strings")

        if "type" in server:
            if server["type"] not in VALID_TRANSPORT_TYPES:
                errors.append(
                    f"{prefix}: 'type' must be one of {sorted(VALID_TRANSPORT_TYPES)}"
                )

        if has_url and not isinstance(server.get("url"), str):
            errors.append(f"{prefix}: 'url' must be a string")

    return errors
