"""
CLI entry point for the local bridge daemon.

Usage:
    nexus-bridge init                     Create a starter config file
    nexus-bridge start --token <JWT>      Start the bridge daemon

The daemon:
1. Reads the YAML config to discover local MCP servers
2. Opens an outbound WebSocket to the production relay
3. Authenticates with the provided JWT
4. Forwards MCP requests from agents to local servers
"""

from __future__ import annotations

import argparse
import asyncio
import logging
import signal
import sys

from .config import DEFAULT_CONFIG_PATH, init_config, load_config
from .server_manager import ServerManager
from .tunnel import BridgeTunnel

DEFAULT_RELAY_URL = "wss://nexusify.ai/ws/bridge/"

logger = logging.getLogger("bridge")


def _setup_logging(verbose: bool) -> None:
    level = logging.DEBUG if verbose else logging.INFO
    logging.basicConfig(
        level=level,
        format="%(asctime)s [%(levelname)s] %(name)s: %(message)s",
        datefmt="%H:%M:%S",
    )


def _parse_args(argv: list[str] | None = None) -> argparse.Namespace:
    parser = argparse.ArgumentParser(
        prog="nexus-bridge",
        description="Nexus Local Bridge — connects MCP servers on your machine to your cloud agents.",
    )
    sub = parser.add_subparsers(dest="command")

    # ── init ──────────────────────────────────────────────────
    init_cmd = sub.add_parser(
        "init",
        help="Create a starter config file with examples",
    )
    init_cmd.add_argument(
        "--config", default=DEFAULT_CONFIG_PATH,
        help=f"Where to write the config (default: {DEFAULT_CONFIG_PATH})",
    )

    # ── start ─────────────────────────────────────────────────
    start = sub.add_parser("start", help="Start the bridge daemon")
    start.add_argument(
        "--token", required=True,
        help="Bridge token (generate one from the app UI)",
    )
    start.add_argument(
        "--config", default=DEFAULT_CONFIG_PATH,
        help=f"Path to bridge config YAML (default: {DEFAULT_CONFIG_PATH})",
    )
    start.add_argument(
        "--relay-url", default=DEFAULT_RELAY_URL,
        help=f"WebSocket URL of the production relay (default: {DEFAULT_RELAY_URL})",
    )
    start.add_argument(
        "--verbose", "-v", action="store_true",
        help="Enable debug logging",
    )

    return parser.parse_args(argv)


def _run_init(args: argparse.Namespace) -> None:
    """Handle the ``init`` sub-command."""
    try:
        created = init_config(args.config)
    except FileExistsError as exc:
        print(f"Already exists: {exc}")
        print("Edit the file to configure your local MCP servers, then run:")
        print("  nexus-bridge start --token <TOKEN>")
        sys.exit(0)

    print(f"Created config at: {created}")
    print()
    print("Next steps:")
    print(f"  1. Open {created} and uncomment the servers you want")
    print("  2. Generate a bridge token from the app (MCP Servers tab)")
    print("  3. Run:  nexus-bridge start --token <TOKEN>")


async def _run_start(args: argparse.Namespace) -> None:
    """Handle the ``start`` sub-command."""
    config = load_config(args.config)

    if not config.servers:
        logger.error(
            "No servers enabled in %s. "
            "Open the file and uncomment at least one server.",
            args.config,
        )
        sys.exit(1)

    logger.info(
        "Loaded %d server(s) from %s: %s",
        len(config.servers), args.config,
        [s.name for s in config.servers],
    )

    server_manager = ServerManager(config.servers)
    tunnel = BridgeTunnel(
        relay_url=args.relay_url,
        token=args.token,
        server_manager=server_manager,
    )

    # Graceful shutdown on SIGINT / SIGTERM
    loop = asyncio.get_running_loop()
    for sig in (signal.SIGINT, signal.SIGTERM):
        try:
            loop.add_signal_handler(sig, lambda: asyncio.create_task(tunnel.stop()))
        except NotImplementedError:
            # Windows doesn't support add_signal_handler; use KeyboardInterrupt
            pass

    try:
        await tunnel.run()
    except KeyboardInterrupt:
        await tunnel.stop()


def main(argv: list[str] | None = None) -> None:
    args = _parse_args(argv)

    if args.command == "init":
        _run_init(args)
    elif args.command == "start":
        _setup_logging(args.verbose)
        asyncio.run(_run_start(args))
    else:
        print("Usage:")
        print("  nexus-bridge init              Create a starter config file")
        print("  nexus-bridge start --token T    Start the bridge daemon")
        print()
        print("First time? Run: nexus-bridge init")
        sys.exit(1)


if __name__ == "__main__":
    main()
