import queue

from ldnode import logger
from ldnode.runner.config import Settings
from ldnode.runner.schemas import Service, BaseContext, BaseWorkerState
from ldnode.runner.events import (
    TaskFinished,
    on, 
    Events, 
    TaskAnswer,
    Ping,
    DataSync,
    TaskCanceled,
)
from .schemas.protocol import NodeAction
from .post_worker import PostWorker
from .ws_worker import WSWorker


class ConnectorService(Service):
    """ 连接服务 """
    def __init__(self, settings: Settings, context: BaseContext):
        super().__init__(settings, context)
        self.running = False
        self.ws_worker_state: BaseWorkerState | None = None
        self.post_worker_state: BaseWorkerState | None = None
        
    async def spawn_workers(self) -> None:
        """ 启动工作进程 """
        self.ws_worker_state = await self.context.register_worker("connector", "ws", WSWorker)
        self.post_worker_state = await self.context.register_worker("connector", "post", PostWorker)
            
    @on(Events.TASK_ANSWER)
    async def handle_task_answer(self, _: str, data: TaskAnswer) -> None:
        """ 处理任务应答 """
        if self.post_worker_state.is_alive():
            await self.post_worker_state.send(data)
        
    @on(Events.PING)
    async def handle_ping(self, _: str, data: Ping) -> None:
        """ 处理心跳 """
        if self.ws_worker_state.is_alive():
            await self.ws_worker_state.send((NodeAction.PING, data))
        
    @on(Events.DATA_SYNC)
    async def handle_data_sync(self, _: str, data: DataSync) -> None:
        """ 处理数据同步 """
        if self.ws_worker_state.is_alive():
            await self.ws_worker_state.send((NodeAction.SYNC_DATA_LOG, data))
    
    @on(Events.TASK_FINISHED)
    async def handle_task_finished(self, _: str, data: TaskFinished) -> None:
        """ 处理释放资源 """
        if self.ws_worker_state.is_alive():
            await self.ws_worker_state.send((NodeAction.FINISHED_TASK, data))
            
    @on(Events.TASK_CANCELED)
    async def handle_task_canceled(self, _: str, data: TaskCanceled) -> None:
        """ 处理任务取消 """
        if self.ws_worker_state.is_alive():
            await self.ws_worker_state.send((NodeAction.CANCELLED_TASK, data))
        
    async def listen_ws_output(self) -> None:
        """ 监听 WebSocket 输出 """
        while self.running:
            try:
                data = await self.ws_worker_state.recv()
                if data is not None:
                    source, event, data = data
                    await self.context.submit_event(source, event, data)
            except queue.Empty:
                continue
            except Exception as e:
                logger.connector.warning(f"监听 WebSocket 输出失败: {e}")

    async def start(self) -> None:
        """ 启动服务 """
        self.running = True
        await self.spawn_workers()
        await self.listen_ws_output()

    async def shutdown(self) -> None:
        """ 关闭服务 """
        self.running = False
