from __future__ import annotations

import logging
import logging.handlers
from pathlib import Path
from time import gmtime
from typing import Final

from delta_barth.constants import (
    ENABLE_LOGGING,
    LOG_FILENAME,
    LOGGING_TO_FILE,
    LOGGING_TO_STDERR,
)

# ** config
logging.Formatter.converter = gmtime
LOG_FMT: Final[str] = "%(asctime)s | lang_main:%(module)s:%(levelname)s | %(message)s"
LOG_DATE_FMT: Final[str] = "%Y-%m-%d %H:%M:%S +0000"
LOGGING_LEVEL_STDERR: Final[int] = logging.INFO
LOGGING_LEVEL_FILE: Final[int] = logging.DEBUG
# ** handlers
NULL_HANDLER = logging.NullHandler()
# ** formatters
LOGGER_ALL_FORMATER = logging.Formatter(fmt=LOG_FMT, datefmt=LOG_DATE_FMT)

# ** loggers and configuration

logger_base = logging.getLogger("delta_barth")
logger_status = logging.getLogger("delta_barth.status")
logger_status.setLevel(logging.DEBUG)
logger_session = logging.getLogger("delta_barth.session")
logger_session.setLevel(logging.DEBUG)
logger_management = logging.getLogger("delta_barth.management")
logger_management.setLevel(logging.DEBUG)
logger_wrapped_results = logging.getLogger("delta_barth.wrapped_results")
logger_wrapped_results.setLevel(logging.DEBUG)
logger_pipelines = logging.getLogger("delta_barth.pipelines")
logger_pipelines.setLevel(logging.DEBUG)
logger_db = logging.getLogger("delta_barth.databases")
logger_db.setLevel(logging.DEBUG)


def setup_logging(
    logging_dir: Path,
) -> None:
    # ** handlers
    LOG_FILE_PATH: Final[Path] = logging_dir / LOG_FILENAME

    if ENABLE_LOGGING and LOGGING_TO_STDERR:
        logger_all_handler_stderr = logging.StreamHandler()
        logger_all_handler_stderr.setLevel(LOGGING_LEVEL_STDERR)
        logger_all_handler_stderr.setFormatter(LOGGER_ALL_FORMATER)
    else:  # pragma: no cover
        logger_all_handler_stderr = NULL_HANDLER

    if ENABLE_LOGGING and LOGGING_TO_FILE:
        logger_all_handler_file = logging.handlers.RotatingFileHandler(
            LOG_FILE_PATH,
            encoding="utf-8",
            maxBytes=5_242_880,
            backupCount=1,
            delay=True,
        )
        logger_all_handler_file.setLevel(LOGGING_LEVEL_FILE)
        logger_all_handler_file.setFormatter(LOGGER_ALL_FORMATER)
    else:  # pragma: no cover
        logger_all_handler_file = NULL_HANDLER

    logger_base.addHandler(logger_all_handler_stderr)
    logger_base.addHandler(logger_all_handler_file)


def disable_logging() -> None:
    handlers = tuple(logger_base.handlers)
    for handler in handlers:
        logger_base.removeHandler(handler)

    logger_base.addHandler(NULL_HANDLER)
