# Copyright (C) 2026 GoodData Corporation

"""CLI handlers for install/init/doctor/migrate commands."""

from __future__ import annotations

import argparse
import sys
from pathlib import Path

from aida_mcp.server import mcp_install
from aida_mcp.server.cli_runtime import run_streamable_http_server
from aida_mcp.server.repo_onboarding import doctor_repo, init_repo, migrate_repo, update_rules


def _resolve_http_url(args: argparse.Namespace) -> str | None:
    if bool(getattr(args, "http", False)):
        return mcp_install.build_http_url(port=getattr(args, "http_port", None))
    return None


def install_mcp(args: argparse.Namespace) -> None:
    command_path = mcp_install.resolve_self_command_path(sys.argv[0])
    portable_command_path = Path("aida-mcp")
    project_root = Path(args.workspace_root).expanduser().resolve() if args.workspace_root else Path.cwd().resolve()
    targets = mcp_install.resolve_targets(args.target)
    http_url = _resolve_http_url(args)
    if not targets:
        print("[aida-mcp][install-mcp][error] No --target provided.")
        print("[aida-mcp][install-mcp][error] Example (project-local): aida-mcp install-mcp --target cursor")
        print("[aida-mcp][install-mcp][error] Example (project-local): aida-mcp install-mcp --target claude")
        print("[aida-mcp][install-mcp][error] Example (project-local): aida-mcp install-mcp --target codex")
        print("[aida-mcp][install-mcp][error] Example (global): aida-mcp install-mcp --global --target cursor")
        print("[aida-mcp][install-mcp][error] Example (global): aida-mcp install-mcp --global --target codex")
        print("[aida-mcp][install-mcp][error] Example (global): aida-mcp install-mcp --global --target jetbrains")
        print("[aida-mcp][install-mcp][error] Example (global): aida-mcp install-mcp --global --target junie")
        raise SystemExit(2)

    for target in targets:
        if target == "cursor":
            if bool(args.global_config):
                mcp_install.install_for_cursor(
                    command_path=command_path,
                    http_url=http_url,
                    workspace_root=args.workspace_root,
                    config_root=args.config_root,
                    allow_global=True,
                )
            else:
                mcp_install.install_for_cursor_project(
                    project_root=project_root,
                    command_path=portable_command_path,
                    http_url=http_url,
                    workspace_root=args.workspace_root,
                    config_root=args.config_root,
                )
        elif target == "claude":
            if bool(args.global_config):
                mcp_install.install_for_claude(
                    command_path=command_path,
                    http_url=http_url,
                    workspace_root=args.workspace_root,
                    config_root=args.config_root,
                    allow_global=True,
                )
            else:
                mcp_install.install_for_claude_project(
                    project_root=project_root,
                    command_path=portable_command_path,
                    http_url=http_url,
                    workspace_root=args.workspace_root,
                    config_root=args.config_root,
                )
        elif target == "codex":
            if bool(args.global_config):
                mcp_install.install_for_codex(
                    command_path=command_path,
                    http_url=http_url,
                    workspace_root=args.workspace_root,
                    config_root=args.config_root,
                    allow_global=True,
                )
            else:
                mcp_install.install_for_codex_project(
                    project_root=project_root,
                    command_path=portable_command_path,
                    http_url=http_url,
                    workspace_root=args.workspace_root,
                    config_root=args.config_root,
                )
        elif target == "jetbrains":
            mcp_install.install_for_jetbrains(
                command_path=command_path,
                http_url=http_url,
                workspace_root=args.workspace_root,
                config_root=args.config_root,
                allow_global=bool(args.global_config),
            )
        elif target == "junie":
            mcp_install.install_for_junie(
                command_path=command_path,
                http_url=http_url,
                workspace_root=args.workspace_root,
                config_root=args.config_root,
                allow_global=bool(args.global_config),
            )

    mcp_install.log("Installation complete. Restart your editor(s) to pick up the MCP server.")


def init_cmd(args: argparse.Namespace) -> None:
    command_path = mcp_install.resolve_self_command_path(sys.argv[0])
    workspace_root = Path(args.workspace_root).expanduser().resolve() if args.workspace_root else Path.cwd().resolve()
    result = init_repo(
        workspace_root=workspace_root,
        command_path=command_path,
        force=bool(args.force),
        http_url=_resolve_http_url(args),
    )
    print("[aida-mcp][init] wrote:")
    for p in result.wrote_files:
        print(f"  - {p}")
    if result.skipped_files:
        print("[aida-mcp][init] skipped (already existed):")
        for p in result.skipped_files:
            print(f"  - {p}")
    print("[aida-mcp][init] note: JetBrains AI Chat and Junie currently ignore repo-local mcp.json files.")
    print("[aida-mcp][init] note: Use global install for those clients:")
    print("  - aida-mcp install-mcp --global --target jetbrains")
    print("  - aida-mcp install-mcp --global --target junie")


def doctor_cmd(args: argparse.Namespace) -> None:
    workspace_root = Path(args.workspace_root).expanduser().resolve() if args.workspace_root else Path.cwd().resolve()
    code = doctor_repo(workspace_root=workspace_root, auto_fix=bool(getattr(args, "auto_fix", False)))
    raise SystemExit(code)


def migrate_cmd(args: argparse.Namespace) -> None:
    command_path = mcp_install.resolve_self_command_path(sys.argv[0])
    workspace_root = Path(args.workspace_root).expanduser().resolve() if args.workspace_root else Path.cwd().resolve()
    result = migrate_repo(
        workspace_root=workspace_root,
        command_path=command_path,
        client_only=bool(args.client_only),
        dry_run=bool(args.dry_run),
        force=bool(args.force),
    )
    print(f"[aida-mcp][migrate] backups_dir: {result.backups_dir}")
    if result.backed_up:
        print("[aida-mcp][migrate] backed up:")
        for p in result.backed_up:
            print(f"  - {p}")
    if result.removed:
        print("[aida-mcp][migrate] removed:")
        for p in result.removed:
            print(f"  - {p}")
    if result.wrote:
        print("[aida-mcp][migrate] wrote:")
        for p in result.wrote:
            print(f"  - {p}")
    if result.config_updates:
        print("[aida-mcp][migrate] config_updates:")
        for item in result.config_updates:
            print(f"  - {item}")


def update_rules_cmd(args: argparse.Namespace) -> None:
    workspace_root = Path(args.workspace_root).expanduser().resolve() if args.workspace_root else Path.cwd().resolve()
    result = update_rules(workspace_root=workspace_root)
    print("[aida-mcp][update-rules] wrote:")
    for p in result.wrote_files:
        print(f"  - {p}")
    if result.skipped_files:
        print("[aida-mcp][update-rules] skipped:")
        for p in result.skipped_files:
            print(f"  - {p}")


def serve_http_cmd(args: argparse.Namespace) -> None:
    run_streamable_http_server(
        host=args.host,
        port=args.port,
        path=args.path,
        workspace_root=args.workspace_root,
    )
