"""Raw console tool — safety-gated direct firmware access."""

from fastmcp import Context

from mcbirdcage.state import BirdcageState

# Commands that are dangerous at the root menu level.
_BLOCKED_ROOT_COMMANDS = {"q"}


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

    @mcp.tool()
    async def send_raw_command(ctx: Context, command: str) -> dict:
        """Send a raw command to the firmware console and return the response.

        This provides direct access to the Winegard firmware shell. The
        command is sent as-is and the raw response is returned.

        SAFETY: The 'q' command at root menu is BLOCKED — it kills the
        UART shell and requires a hardware power cycle to recover.

        HAZARDOUS COMMANDS (use with caution):
        - ADC 'scan' without arguments on uncalibrated AZ: deadlocks shell
        - NVS 'e <idx> <value>': writes to non-volatile storage
        - 'reboot': reboots the microcontroller
        - 'stow': folds dish flat (modified feeds may not survive)

        After a raw command, the menu state is marked as unknown.

        Args:
            command: The firmware command string to send.
        """
        state: BirdcageState = ctx.request_context.lifespan_context
        if state.device is None:
            raise RuntimeError("No device connected. Use the 'connect' tool first.")

        cmd_stripped = command.strip().lower()
        if cmd_stripped in _BLOCKED_ROOT_COMMANDS:
            return {
                "error": f"Command '{command}' is blocked for safety. "
                "The 'q' command kills the UART shell and requires "
                "a hardware power cycle to recover.",
                "blocked": True,
            }

        raw = state.device.send_raw(command)
        return {"response": raw}
