"""gRPC server 启动与管理.

使用 grpc.aio 异步 server，端口 50058（port-allocation.md §3/§5/§7 权威源）。
"""

from typing import Any

import grpc
import structlog

from ..proto_gen import ai_pb2_grpc
from .interceptors import AuthInterceptor, ErrorInterceptor, LoggingInterceptor
from .servicer import AiServicer

logger = structlog.get_logger()


class GrpcServer:
    """gRPC server 管理器.

    用法：
        server = GrpcServer(port=50058, servicer=servicer)
        await server.start()
        ...
        await server.stop()
    """

    def __init__(
        self,
        port: int = 50058,
        servicer: AiServicer | None = None,
        max_workers: int = 10,
    ) -> None:
        self._port = port
        self._servicer = servicer or AiServicer()
        self._max_workers = max_workers
        self._server: grpc.aio.Server | None = None

    async def start(self) -> None:
        """启动 gRPC server.

        注意：grpc.aio.server 的 interceptors 需要 grpc.aio.ServerInterceptor 基类，
        当前拦截器使用同步 grpc.ServerInterceptor 基类会报 ValueError。
        此处 try/except 降级为无拦截器启动，避免阻塞服务启动。
        """
        interceptors = [LoggingInterceptor(), AuthInterceptor(), ErrorInterceptor()]
        try:
            self._server = grpc.aio.server(interceptors=interceptors)
        except (ValueError, TypeError):
            logger.warning("grpc_interceptors_incompatible_start_without")
            self._server = grpc.aio.server()
        ai_pb2_grpc.add_AiServiceServicer_to_server(self._servicer, self._server)
        self._server.add_insecure_port(f"[::]:{self._port}")
        await self._server.start()
        logger.info("grpc_server_started", port=self._port)

    async def stop(self, grace: float = 5.0) -> None:
        """优雅关闭 gRPC server."""
        if self._server is not None:
            await self._server.stop(grace=grace)
            logger.info("grpc_server_stopped", port=self._port)

    @property
    def is_running(self) -> bool:
        return self._server is not None


def create_grpc_server(
    port: int,
    chat_service: Any = None,
    question_service: Any = None,
    expression_service: Any = None,
    workflow_service: Any = None,
) -> GrpcServer:
    """创建 gRPC server（工厂函数）."""
    servicer = AiServicer(
        chat_service=chat_service,
        question_service=question_service,
        expression_service=expression_service,
        workflow_service=workflow_service,
    )
    return GrpcServer(port=port, servicer=servicer)
