import datetime
import logging
import sys
from zoneinfo import ZoneInfo

from constants import LAUNCH_ON_LOCAL, LOG_DATE_FORMAT, LOG_FORMAT
from environments import LOG_LEVEL, TZ


class SingletonLogger:
    __logger: logging.Logger = None

    def __init__(self) -> None:
        # logger設定
        logger = logging.getLogger()
        formatter = logging.Formatter(
            LOG_FORMAT,
            LOG_DATE_FORMAT
        )
        formatter.converter = lambda *arg: datetime.datetime.now(ZoneInfo(TZ)).timetuple()
        # ローカル環境で動かす場合、標準出力ハンドラーを追加する
        # AWS Lambda上では`LambdaLoggerHandler`がデフォルトでセットされている
        if len(sys.argv) == 2 and sys.argv[1] == LAUNCH_ON_LOCAL:
            localHandler = logging.StreamHandler()
            logger.addHandler(localHandler)
        for handler in logger.handlers:
            handler.setFormatter(formatter)
        level = logging.getLevelName(LOG_LEVEL)
        logger.setLevel(level)

        self.__logger = logger

    def debug(self, log_id: str, msg: str):
        self._log(logging.DEBUG, log_id, msg)

    def info(self, log_id: str, msg: str):
        self._log(logging.INFO, log_id, msg)

    def warning(self, log_id: str, msg: str):
        self._log(logging.WARNING, log_id, msg)

    def error(self, log_id: str, msg: str):
        self._log(logging.ERROR, log_id, msg)

    def exception(self, log_id: str, msg: str):
        self._log(logging.ERROR, log_id, msg, exc_info=True)

    def _log(self, log_level: int, log_id: str, msg: str, exc_info=False):
        self.__logger.log(log_level, f'{log_id} {msg}', exc_info=exc_info)


class MeDaCaLogger:
    __unique_instance: logging.Logger = None

    @staticmethod
    def get_logger() -> SingletonLogger:
        # インスタンス未生成の場合、唯一のインスタンスを生成する
        if not MeDaCaLogger.__unique_instance:
            MeDaCaLogger.__unique_instance = SingletonLogger()
        return MeDaCaLogger.__unique_instance
