
from dataclasses import dataclass
from injector import inject,singleton
import yaml
import sys
import logging

@singleton
class Configuration():

    @inject
    def __init__(self) -> None:
        config_file_path = ""
        try:
            config_file_path = sys.argv[1]
        except:
            config_file_path = ".env.yaml"
        with open(config_file_path) as f:
            cfg = yaml.load(f, Loader=yaml.FullLoader)
            self.cfg = cfg
    
    def getDict(self):
        return self.cfg

    """
    # yaml 檔中的路徑 get("aaa.bbb.ccc")
    aaa:
      bbb:
         ccc: "hello world"
    """
    def get(self, path: str | list[str], cfg: dict = None, default=None):
        if isinstance(path, str):
            if cfg is None:
                cfg = self.cfg
            return self.get(path.split("."), cfg)
        length = len(path)
        if length == 0  or not isinstance(cfg, dict):
            return default
        if length == 1:
            return cfg.get(path[0])
        return self.get(path[1:], cfg.get(path[0]))

class TesouConf():
    url: str
    
    @inject
    def __init__(self, config: Configuration) -> None:
        self.url = config.get("tesou.url")


class MeloConf():
    mode: str
    url: str
    speed: int
    device: str
    language: str
    speaker: str

    @inject
    def __init__(self, config: Configuration) -> None:
        self.mode = config.get("melotts.mode")
        self.url = config.get("melotts.url")
        self.speed = config.get("melotts.speed")
        self.device = config.get("melotts.device")
        self.language = config.get("melotts.language")
        self.speaker = config.get("melotts.speaker")

class CosyVoiceConf():
    mode: str
    url: str
    speed: int
    device: str
    language: str
    speaker: str

    @inject
    def __init__(self, config: Configuration) -> None:
        self.mode = config.get("cosyvoicetts.mode")
        self.url = config.get("cosyvoicetts.url")
        self.speed = config.get("cosyvoicetts.speed")
        self.device = config.get("cosyvoicetts.device")
        self.language = config.get("cosyvoicetts.language")
        self.speaker = config.get("cosyvoicetts.speaker")

class SovitsConf():
    mode: str
    url: str
    speed: int
    device: str
    language: str
    speaker: str

    @inject
    def __init__(self, config: Configuration) -> None:
        self.mode = config.get("sovitstts.mode")
        self.url = config.get("sovitstts.url")
        self.speed = config.get("sovitstts.speed")
        self.device = config.get("sovitstts.device")
        self.language = config.get("sovitstts.language")
        self.speaker = config.get("sovitstts.speaker")

        self.text_lang = config.get("sovitstts.text_lang")
        self.ref_audio_path = config.get("sovitstts.ref_audio_path")
        self.prompt_lang = config.get("sovitstts.prompt_lang")
        self.prompt_text = config.get("sovitstts.prompt_text")
        self.text_split_method = config.get("sovitstts.text_split_method")
        self.batch_size = config.get("sovitstts.batch_size")
        self.media_type = config.get("sovitstts.media_type")
        self.streaming_mode = config.get("sovitstts.streaming_mode")

class SenseVoiceConf():
    mode: str
    url: str
    speed: int
    device: str
    language: str
    speaker: str

    @inject
    def __init__(self, config: Configuration) -> None:
        self.mode = config.get("sensevoiceasr.mode")
        self.url = config.get("sensevoiceasr.url")
        self.speed = config.get("sensevoiceasr.speed")
        self.device = config.get("sensevoiceasr.device")
        self.language = config.get("sensevoiceasr.language")
        self.speaker = config.get("sensevoiceasr.speaker")

@singleton
class EnvConf():
    version: str
    host: str
    port: str
    @inject
    def __init__(self, config: Configuration) -> None:
        self.version = "0.0.1"
        self.host = config.get("env.host", default="0.0.0.0")
        self.port = config.get("env.port", default="8080")

@singleton
@dataclass
class BlackboxConf():
    lazyloading: bool

    @inject
    def __init__(self, config: Configuration) -> None:
        self.lazyloading = bool(config.get("blackbox.lazyloading", default=False))

@singleton
class VLMConf():

    @inject
    def __init__(self, config: Configuration) -> None:
        self.urls = config.get("vlms.urls")
