#! python3  # noqa: E265

"""Helper to configure logging depending on CLI options."""

# ############################################################################
# ########## IMPORTS #############
# ################################

# standard library
import logging
from getpass import getuser
from logging.handlers import RotatingFileHandler
from os import getenv
from pathlib import Path
from platform import architecture, platform, uname
from socket import gethostname

# 3rd party
import certifi
from requests.utils import DEFAULT_CA_BUNDLE_PATH

# Imports depending on operating system
if "linux" in uname().system.lower():
    import distro
else:
    distro = None

# package
from qgis_deployment_toolbelt.__about__ import __title__, __version__
from qgis_deployment_toolbelt.constants import get_qdt_logs_folder
from qgis_deployment_toolbelt.utils.proxies import get_proxy_settings

# ############################################################################
# ########## GLOBALS #############
# ################################

# logs
logger = logging.getLogger(__name__)

# ############################################################################
# ########## FUNCTIONS ###########
# ################################


def configure_logger(verbosity: int = 1, logfile: Path = None):
    """Configure logging according to verbosity from CLI.

    Args:
        verbosity (int): verbosity level
        logfile (Path, optional): file where to store log. Defaults to None.
    """
    # handle log level overridden by environment variable
    verbosity = getenv("QDT_LOGS_LEVEL", verbosity)
    try:
        verbosity = int(verbosity)
    except ValueError as err:
        logger.error(f"Bad verbosity value type: {err}. Fallback to 1.")
        verbosity = 1

    # set log level depending on verbosity argument
    if 0 < verbosity < 4:
        verbosity = 40 - (10 * verbosity)
    elif verbosity >= 4:
        # debug is the limit
        verbosity = 40 - (10 * 3)
    else:
        verbosity = 0

    # set console handler
    log_console_handler = logging.StreamHandler()
    log_console_handler.setLevel(verbosity)

    # set log file
    if not logfile:
        logging.basicConfig(
            level=verbosity,
            format="%(asctime)s||%(levelname)s||%(module)s||%(funcName)s||%(lineno)d||%(message)s",
            datefmt="%Y-%m-%d %H:%M:%S",
            handlers=[log_console_handler],
        )

    else:
        logs_folder = get_qdt_logs_folder()

        # make sure folder exists
        logs_folder.mkdir(exist_ok=True, parents=True)
        logs_filepath = Path(logs_folder, logfile)

        log_file_handler = RotatingFileHandler(
            backupCount=10,
            delay=True,
            encoding="UTF-8",
            filename=logs_filepath,
            maxBytes=3000000,
            mode="a",
        )

        # force new file by execution
        if logs_filepath.is_file():
            log_file_handler.doRollover()

        logging.basicConfig(
            level=verbosity,
            format="%(asctime)s||%(levelname)s||%(module)s||%(funcName)s||%(lineno)d||%(message)s",
            datefmt="%Y-%m-%d %H:%M:%S",
            handlers=[log_console_handler, log_file_handler],
        )

        logger.info(f"Log file: {logs_filepath}")

    headers()


def headers():
    """Basic information to log before other message."""
    # initialize the log
    logger.info(f"{'='*10} {__title__} - {__version__} {'='*10}")
    logger.debug(f"Operating System: {platform()}")
    if distro:
        logger.debug(
            f"Distribution name and version: {distro.name()} {distro.version()}"
        )
    logger.debug(f"Architecture: {architecture()[0]}")
    logger.debug(f"Computer: {gethostname()}")
    logger.debug(f"Launched by user: {getuser()}")

    if getenv("userdomain"):
        logger.debug(f"OS Domain: {getenv('userdomain')}")
    else:
        logger.debug("No OS domain detected.")

    if proxies_settings := get_proxy_settings():
        logger.debug(f"Network proxies detected: {proxies_settings}")
    else:
        logger.debug("No network proxies detected")

    # SSL CA certificates
    logger.debug(f"Installed certificate authority (CA) bundle: {certifi.where()}")
    logger.debug(f"Default certificate authority (CA) bundle: {DEFAULT_CA_BUNDLE_PATH}")
    logger.debug(
        f"Certificate authority (CA) bundle to use: {getenv('REQUESTS_CA_BUNDLE', getenv('CURL_CA_BUNDLE'))}"
    )


def get_logger_filepath() -> Path | None:
    """Retrieve log filepath within logger handlers.

    Returns:
        Path | None: path to the logfile or None if no handler has baseFilename attr.
    """
    if logger.root.hasHandlers():
        for handler in logger.root.handlers:
            if hasattr(handler, "baseFilename"):
                return Path(handler.baseFilename)

    logger.warning("No file found in ay log handlers.")
    return None
