import functools
import logging
import os
import sys
import time

from loguru import logger


class InterceptHandler(logging.Handler):
    def emit(self, record):
        # Get corresponding Loguru level if it exists
        try:
            level = logger.level(record.levelname).name
        except ValueError:
            level = record.levelno

        # Find caller from where originated the logged message
        frame, depth = logging.currentframe(), 6
        while frame.f_code.co_filename == logging.__file__:
            frame = frame.f_back
            depth += 1
        logger.opt(depth=depth, exception=record.exc_info).log(
            level, record.getMessage()
        )


def setting_log(
    save_file=False,
    openai_route_prefix=None,
    log_name="openai_forward",
    multi_process=True,
    **kwargs,
):
    """
    Configures the logging settings for the application.
    """
    # TODO 修复时区配置
    if os.environ.get("TZ") == "Asia/Shanghai":
        os.environ["TZ"] = "UTC-8"
        if hasattr(time, "tzset"):
            time.tzset()

    logging.root.handlers = [InterceptHandler()]
    for name in logging.root.manager.loggerDict.keys():
        logging.getLogger(name).handlers = []
        logging.getLogger(name).propagate = True

    print_chat = kwargs.get('print_chat')
    config_handlers = [
        {"sink": sys.stdout, "level": "INFO" if print_chat else "DEBUG"},
    ]

    def filter_func(_prefix, _postfix, record):
        chat_key = f"{_prefix}{_postfix}"
        return chat_key in record["extra"]

    for prefix in openai_route_prefix or []:
        _prefix = prefix.replace('/', '_')

        config_handlers.extend(
            [
                {
                    "sink": f"./Log/chat/{_prefix}/chat.log",
                    "enqueue": multi_process,
                    "rotation": "50 MB",
                    "filter": functools.partial(filter_func, _prefix, "_chat"),
                    "format": "{message}",
                },
                {
                    "sink": f"./Log/whisper/{_prefix}/whisper.log",
                    "enqueue": multi_process,
                    "rotation": "30 MB",
                    "filter": functools.partial(filter_func, _prefix, "_whisper"),
                    "format": "{message}",
                },
            ]
        )

    if save_file:
        config_handlers += [
            {
                "sink": f"./Log/{log_name}.log",
                "enqueue": multi_process,
                "rotation": "100 MB",
                "level": "INFO",
            }
        ]

    logger_config = {"handlers": config_handlers}
    logger.configure(**logger_config)
