"""linear-canal serve — Start the MCP stdio server for AI agents.

Starts the MCP server using stdio transport for Claude Code, Cursor, and other MCP clients.

IMPORTANT: The MCP stdio protocol requires that stdout carries ONLY JSON-RPC messages.
All human-readable logging/banners are written to stderr to avoid polluting the channel.
"""

from __future__ import annotations

import logging
import os
import sys
from pathlib import Path
from typing import Optional

import click
from rich.console import Console
from rich.panel import Panel

# CRITICAL: stderr-only console — stdout must stay clean for JSON-RPC
stderr_console = Console(stderr=True)


@click.command("serve")
@click.option(
    "--project",
    "-p",
    type=click.Path(exists=True, file_okay=False),
    default=".",
    help="Path to the project (uses current directory if not specified)",
)
@click.option(
    "--project-id",
    default=None,
    envvar="PROJECT_ID",
    help="Project ID override (default: directory name of --project)",
)
@click.option(
    "--lancedb-path",
    default=None,
    envvar="LANCEDB_PATH",
    help="LanceDB global store path (default: ~/.linear-canal/data/lancedb_global_store)",
)
@click.option(
    "--ctx-dir",
    default=None,
    envvar="CTX_DIR",
    help="Context files directory (default: .linear_canal_data/<project>/ctx)",
)
@click.option(
    "--log-level",
    default="INFO",
    envvar="LOG_LEVEL",
    type=click.Choice(["DEBUG", "INFO", "WARNING", "ERROR"]),
    help="Log level",
)
@click.pass_context
def serve_cmd(
    ctx: click.Context,
    project: str,
    project_id: Optional[str],
    lancedb_path: Optional[str],
    ctx_dir: str,
    log_level: str,
) -> None:
    """Start the Linear Canal MCP server (stdio transport).

    This server speaks the MCP 1.0 protocol over stdin/stdout, making it
    compatible with Claude Code, Cursor, and other MCP clients.

    The server will run until interrupted and will handle incoming tool
    calls from the connected AI agent.
    """
    import asyncio

    # Route all Python logging to stderr so stdout stays JSON-RPC only
    logging.basicConfig(
        stream=sys.stderr,
        level=getattr(logging, log_level),
        format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
    )

    project_path = Path(project).resolve()
    project_id = project_id or project_path.name

    from pathlib import Path as _Path
    _default_lancedb = str(_Path.home() / ".linear-canal" / "data" / "lancedb_global_store")
    resolved_lancedb = lancedb_path or _default_lancedb
    resolved_ctx_dir = ctx_dir or str(
        project_path / ".linear_canal_data" / project_id / "ctx"
    )

    # All banner output goes to stderr — never stdout
    stderr_console.print(
        Panel(
            f"[bold blue]Linear Canal MCP Server (stdio transport)[/bold blue]\n"
            f"Project:  {project_path}\n"
            f"LanceDB:  {resolved_lancedb}\n"
            f"CTX Dir:  {resolved_ctx_dir}",
            border_style="blue",
        ),
    )
    stderr_console.print("[dim]Starting MCP server... Press Ctrl+C to stop.[/dim]\n")

    os.environ["PROJECT_ID"] = project_id
    os.environ["LANCEDB_PATH"] = resolved_lancedb
    os.environ["CTX_DIR"] = resolved_ctx_dir
    os.environ["LOG_LEVEL"] = log_level

    try:
        from api.mcp.stdio import StdioMCPServer

        server = StdioMCPServer(
            project_id=project_id,
            lancedb_path=resolved_lancedb,
            ctx_dir=resolved_ctx_dir,
        )

        asyncio.run(server.run())

    except KeyboardInterrupt:
        stderr_console.print("\n[yellow]Server stopped by user[/yellow]")
        sys.exit(0)
    except ImportError as e:
        stderr_console.print(
            f"[red]Error: Could not import MCP server: {e}[/red]\n"
            "[yellow]Make sure linear-canal-api is installed:[/yellow]\n"
            "  pip install -e services/api/"
        )
        sys.exit(1)
    except Exception as e:
        stderr_console.print(f"[red]Error: {e}[/red]")
        sys.exit(1)
