"""
Request handlers for IPC server.
"""

from typing import Any, Callable, Optional

from airctl.common.logging import get_logger
from airctl.ipc.protocol import IPCErrorCode, IPCError

logger = get_logger(__name__)

HandlerFunc = Callable[[dict[str, Any]], Any]


class RequestHandlers:
    """
    Registry for IPC request handlers.
    
    Maps method names to handler functions.
    """

    def __init__(self) -> None:
        self._handlers: dict[str, HandlerFunc] = {}
        self._register_default_handlers()

    def _register_default_handlers(self) -> None:
        """Register default handlers."""
        self.register("daemon.stop", self._handle_daemon_stop)
        self.register("daemon.status", self._handle_daemon_status)

    def register(self, method: str, handler: HandlerFunc) -> None:
        """Register a handler for a method."""
        self._handlers[method] = handler

    def unregister(self, method: str) -> None:
        """Unregister a handler."""
        self._handlers.pop(method, None)

    def has_handler(self, method: str) -> bool:
        """Check if a handler exists for a method."""
        return method in self._handlers

    async def handle(self, method: str, params: Optional[dict[str, Any]]) -> Any:
        """
        Handle a request.

        Args:
            method: Method name
            params: Method parameters

        Returns:
            Handler result

        Raises:
            IPCError: If handler not found or handler raises error
        """
        if not self.has_handler(method):
            raise IPCError(
                code=IPCErrorCode.METHOD_NOT_FOUND,
                message=f"Method not found: {method}",
            )

        handler = self._handlers[method]
        params = params or {}

        try:
            import asyncio
            import inspect

            if inspect.iscoroutinefunction(handler):
                return await handler(params)
            else:
                return handler(params)
        except IPCError:
            raise
        except Exception as e:
            logger.exception(f"Handler error for {method}: {e}")
            raise IPCError(
                code=IPCErrorCode.INTERNAL_ERROR,
                message=str(e),
            )

    def _handle_daemon_stop(self, params: dict[str, Any]) -> dict[str, Any]:
        """Handle daemon stop request."""
        from airctl.daemon.server import request_daemon_stop

        request_daemon_stop()
        return {"success": True}

    def _handle_daemon_status(self, params: dict[str, Any]) -> dict[str, Any]:
        """Handle daemon status request."""
        import os

        return {
            "running": True,
            "pid": os.getpid(),
        }
