# Why does this file exist, and why not put this in `__main__`?
#
# You might be tempted to import things from `__main__` later,
# but that will cause problems: the code will get executed twice:
#
# - When you run `python -m unblu_mcp` python will execute
#   `__main__.py` as a script. That means there won't be any
#   `unblu_mcp.__main__` in `sys.modules`.
# - When you import `__main__` it will get executed again (as a module) because
#   there's no `unblu_mcp.__main__` in `sys.modules`.

from __future__ import annotations

import argparse
import sys
from typing import TYPE_CHECKING, Any

from unblu_mcp._internal import debug

if TYPE_CHECKING:
    from fastmcp import FastMCP


class _DebugInfo(argparse.Action):
    def __init__(self, nargs: int | str | None = 0, **kwargs: Any) -> None:
        super().__init__(nargs=nargs, **kwargs)

    def __call__(self, *args: Any, **kwargs: Any) -> None:  # noqa: ARG002
        debug._print_debug_info()
        sys.exit(0)


def get_parser() -> argparse.ArgumentParser:
    """Return the CLI argument parser.

    Returns:
        An argparse parser.
    """
    parser = argparse.ArgumentParser(
        prog="unblu-mcp",
        description="Unblu MCP Server - Token-efficient access to Unblu API",
    )
    parser.add_argument("-V", "--version", action="version", version=f"%(prog)s {debug._get_version()}")
    parser.add_argument("--debug-info", action=_DebugInfo, help="Print debug information.")
    parser.add_argument(
        "--spec",
        type=str,
        default=None,
        help="Path to swagger.json OpenAPI spec file.",
    )
    parser.add_argument(
        "--policy",
        type=str,
        default=None,
        help="Path to Eunomia policy JSON file for authorization. Requires unblu-mcp[safety].",
    )
    parser.add_argument(
        "--provider",
        type=str,
        choices=["default", "k8s"],
        default="default",
        help="Connection provider to use (default: default).",
    )
    parser.add_argument(
        "--environment",
        type=str,
        default="dev",
        help="K8s environment name (only with --provider k8s). Default: dev.",
    )
    parser.add_argument(
        "--k8s-config",
        type=str,
        default=None,
        help="Path to K8s environments YAML config file (only with --provider k8s).",
    )
    return parser


def main(args: list[str] | None = None) -> int:
    """Run the main program.

    This function is executed when you type `unblu-mcp` or `python -m unblu_mcp`.

    Parameters:
        args: Arguments passed from the command line.

    Returns:
        An exit code.
    """
    parser = get_parser()
    if args == []:
        parser.print_help()
        return 0
    opts = parser.parse_args(args=args)

    provider = _get_provider(opts.provider, opts.environment, opts.k8s_config)
    server = _create_server(spec_path=opts.spec, policy_file=opts.policy, provider=provider)
    server.run()
    return 0


def _get_provider(provider_type: str, environment: str, k8s_config: str | None = None) -> Any:
    """Get the appropriate connection provider based on CLI args."""
    if provider_type == "k8s":
        from unblu_mcp._internal.providers_k8s import (  # noqa: PLC0415
            K8sConnectionProvider,
            _load_environments_from_yaml,
        )

        environments = None
        if k8s_config:
            from pathlib import Path  # noqa: PLC0415

            environments = _load_environments_from_yaml(Path(k8s_config))
            if not environments:
                msg = f"No environments found in {k8s_config}"
                raise ValueError(msg)

        return K8sConnectionProvider(environment=environment, environments=environments)
    # Default provider will be created by create_server from env vars
    return None


def _create_server(
    spec_path: str | None = None,
    policy_file: str | None = None,
    provider: Any = None,
) -> FastMCP:
    """Lazy import to avoid circular imports and top-level import issues."""
    from unblu_mcp._internal.server import create_server  # noqa: PLC0415

    return create_server(spec_path=spec_path, policy_file=policy_file, provider=provider)
