"""能力服务层

Host 端实现的能力服务，处理来自插件的 cap.* 请求。
每个能力方法被注册到 RPC Server，接收 Runner 转发的请求并执行实际操作。
"""

from typing import Any, Callable, Dict, List, Coroutine, TYPE_CHECKING

from src.common.logger import get_logger
from src.plugin_runtime.protocol.envelope import CapabilityRequestPayload, CapabilityResponsePayload, Envelope
from src.plugin_runtime.protocol.errors import ErrorCode, RPCError

if TYPE_CHECKING:
    from src.plugin_runtime.host.authorization import AuthorizationManager

logger = get_logger("plugin_runtime.host.capability_service")

# 能力实现函数类型: (plugin_id, capability, args) -> result
CapabilityImpl = Callable[[str, str, Dict[str, Any]], Coroutine[Any, Any, Any]]


class CapabilityService:
    """能力服务

    负责：
    1. 注册能力实现
    2. 接收插件的能力调用请求
    3. 通过策略引擎校验权限和限流
    4. 执行实际操作并返回结果
    """

    def __init__(self, authorization: "AuthorizationManager") -> None:
        """初始化能力服务。

        Args:
            authorization: 能力授权管理器。
        """
        self._authorization = authorization
        # capability_name -> implementation
        self._implementations: Dict[str, CapabilityImpl] = {}

    def register_capability(self, name: str, impl: CapabilityImpl) -> None:
        """注册一个能力实现

        Args:
            name: 能力名称，如 "send.text", "db.query", "llm.generate"
            impl: 实现函数
        """
        self._implementations[name] = impl
        logger.debug(f"注册能力实现: {name}")

    async def handle_capability_request(self, envelope: Envelope) -> Envelope:
        """处理能力调用请求（作为 RPC Server 的 method handler）

        从 envelope 中提取 capability 名称和参数，
        校验权限后调用对应实现。
        """
        plugin_id = envelope.plugin_id

        try:
            req = CapabilityRequestPayload.model_validate(envelope.payload)
        except Exception as exc:
            return envelope.make_error_response(ErrorCode.E_BAD_PAYLOAD.value, f"能力调用 payload 非法: {exc}")

        capability = req.capability
        args = req.args

        # 1. 权限校验
        allowed, reason = self._authorization.check_capability(plugin_id, capability)
        if not allowed:
            return envelope.make_error_response(ErrorCode.E_CAPABILITY_DENIED.value, reason)

        # 2. 查找实现
        impl = self._implementations.get(capability)
        if impl is None:
            return envelope.make_error_response(ErrorCode.E_METHOD_NOT_ALLOWED.value, f"未注册的能力: {capability}")

        # 3. 执行
        try:
            result = await impl(plugin_id, capability, args)
            resp_payload = CapabilityResponsePayload(success=True, result=result)
            return envelope.make_response(payload=resp_payload.model_dump())
        except RPCError as e:
            return envelope.make_error_response(e.code.value, e.message, e.details)
        except Exception as e:
            logger.error(f"能力 {capability} 执行异常: {e}", exc_info=True)
            return envelope.make_error_response(ErrorCode.E_CAPABILITY_FAILED.value, str(e))

    def list_capabilities(self) -> List[str]:
        """列出所有已注册的能力"""
        return list(self._implementations.keys())
