"""
-*- encoding: utf-8 -*-

Runner类
所有的Runner都对应一个fastapi的endpoint, 
Runner需要处理: 
1.新的websocket 进来后放到 unknow_websocket_pool中
2.收到特定消息后, 将消息转发给特定的pipeline处理
3.管理pipeline与websocket对应关系, 管理pipeline的ID
4.管理pipeline的启动和停止
5.管理所有pipeline用到的资源, 管理pipeline的存活时间。
"""

from abc import ABC, abstractmethod
from typing import Dict, Any, List
from threading import Thread, Lock
from queue import Queue
import traceback
import time

from src.audio_chunk import AudioChunk, AudioBinary
from src.pipeline import Pipeline, PipelineFactory
from src.core.model_loader import ModelLoader
from src.utils.logger import get_module_logger

logger = get_module_logger(__name__)

audio_chunk = AudioChunk()
models_loaded = ModelLoader()


class RunnerBase(ABC):
    """
    运行器基类
    定义了运行器的基本接口
    """
    def __init__(self, *args, **kwargs):
        pass

class STTRunnerFactory:
    """
    STT Runner工厂类
    用于创建运行器实例
    """

    @staticmethod
    def _create_runner(
        audio_binary_name: str,
        model_name_list: List[str],
        pipeline_name_list: List[str],
    ) -> STTRunner:
        """
        创建运行器
        参数:
            audio_binary_name: 音频二进制名称
            model_name_list: 模型名称列表
            pipeline_name_list: 管道名称列表
        返回:
            Runner实例
        """
        audio_binary = audio_chunk.get_audio_binary(audio_binary_name)
        models: Dict[str, Any] = {
            model_name: models_loaded.models[model_name]
            for model_name in model_name_list
        }
        pipelines: List[Pipeline] = [
            PipelineFactory.create_pipeline(pipeline_name)
            for pipeline_name in pipeline_name_list
        ]
        return STTRunner(
            audio_binary_list=[audio_binary], models=models, pipeline_list=pipelines
        )

    @classmethod
    def create_runner_from_config(
        cls,
        config: Dict[str, Any],
    ) -> STTRunner:
        """
        从配置创建运行器
        参数:
            config: 配置字典
        返回:
            Runner实例
        """
        audio_binary_name = config["audio_binary_name"]
        model_name_list = config["model_name_list"]
        pipeline_name_list = config["pipeline_name_list"]
        return cls._create_runner(
            audio_binary_name, model_name_list, pipeline_name_list
        )

    @classmethod
    def create_runner_normal(cls) -> STTRunner:
        """
        创建默认运行器
        返回:
            Runner实例
        """
        audio_binary_name = None
        model_name_list = list(models_loaded.models.keys())
        pipeline_name_list = None
        return cls._create_runner(
            audio_binary_name, model_name_list, pipeline_name_list
        )
