
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")

# 'CRITICAL': CRITICAL,
# 'FATAL': FATAL,
# 'ERROR': ERROR,
# 'WARN': WARNING,
# 'WARNING': WARNING,
# 'INFO': INFO,
# 'DEBUG': DEBUG,
# 'NOTSET': NOTSET,
DEFAULT_LEVEL="WARNING"
DEFAULT_TIME_FORMAT="%Y-%m-%d %H:%M:%S"

@singleton
class LogConf():
    level: int
    time_format = "%Y-%m-%d %H:%M:%S"
    filename: str | None
    @inject
    def __init__(self, config: Configuration) -> None:
        self.level = config.get("log.level")
        c = config.get("log.level", default=DEFAULT_LEVEL).upper()
        level=logging._nameToLevel.get(c)
        if level is None:
            self.level = logging.WARNING
        else:
            self.level = level
        self.filename = config.get("log.filename")
        self.time_format = config.get("log.time_format", default=DEFAULT_TIME_FORMAT)

@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))