"""Connection management tools — connect, disconnect, status."""

from fastmcp import Context

from mcbirdcage.state import BirdcageState


def register(mcp):
    """Register connection tools on the FastMCP instance."""

    @mcp.tool()
    async def connect(
        ctx: Context,
        port: str = "",
        firmware: str = "",
        skip_init: bool = False,
    ) -> dict:
        """Connect to a Winegard satellite dish via RS-422/RS-485 serial.

        In demo mode this is a no-op (already connected). In hardware mode,
        opens the serial port and optionally runs the firmware initialization
        sequence (kills TV satellite search, enters motor submenu).

        Args:
            port: Serial port path (e.g. /dev/ttyUSB0). Defaults to
                BIRDCAGE_PORT env var.
            firmware: Firmware variant: "g2", "hal205", or "hal000".
                Defaults to BIRDCAGE_FIRMWARE env var.
            skip_init: If True, skip firmware init (useful for
                reconnecting to a running dish).
        """
        state: BirdcageState = ctx.request_context.lifespan_context

        if state.demo_mode:
            return {
                "status": "connected",
                "mode": "demo",
                "message": "Demo device already connected",
            }

        if state.connected and state.device is not None:
            return {
                "status": "already_connected",
                "port": state.serial_port,
            }

        serial_port = port or state.serial_port
        fw = firmware or state.firmware_name

        from birdcage.bridge import SerialBridge
        from birdcage.protocol import get_protocol

        protocol = get_protocol(fw)
        device = SerialBridge(protocol)
        device.connect(serial_port)

        if not skip_init:
            device.initialize()

        state.device = device
        state.serial_port = serial_port
        state.firmware_name = fw
        state.connected = True

        return {
            "status": "connected",
            "port": serial_port,
            "firmware": fw,
            "initialized": not skip_init,
        }

    @mcp.tool()
    async def disconnect(ctx: Context) -> dict:
        """Disconnect from the satellite dish and release the serial port.

        In demo mode this is a no-op. In hardware mode, returns to the
        root menu and closes the serial connection cleanly.
        """
        state: BirdcageState = ctx.request_context.lifespan_context

        if state.demo_mode:
            return {"status": "demo", "message": "Demo mode — nothing to disconnect"}

        if state.device is None or not state.connected:
            return {"status": "not_connected"}

        state.device.disconnect()
        state.device = None
        state.connected = False

        return {"status": "disconnected"}

    @mcp.tool()
    async def status(ctx: Context) -> dict:
        """Get current connection status and configuration.

        Returns whether the dish is connected, the serial port, firmware
        variant, demo mode flag, and current menu state (if connected).
        """
        state: BirdcageState = ctx.request_context.lifespan_context

        result = {
            "connected": state.connected,
            "demo_mode": state.demo_mode,
            "serial_port": state.serial_port,
            "firmware": state.firmware_name,
        }

        if state.device is not None and hasattr(state.device, "current_menu"):
            result["current_menu"] = state.device.current_menu

        return result
