""" lib/logger.py """

import functools
import logging
import os
from logging.handlers import RotatingFileHandler

from lib.project import app
from lib.project import env

DEBUG = logging.DEBUG
INFO = logging.INFO
WARNING = logging.WARNING
ERROR = logging.ERROR
EXCEPTION = CRITICAL = FATAL = logging.CRITICAL


class LogConfig:

    _updated = []

    def __init__(self, level=INFO):
        self.file = "/var/www/piapp/logs/app.log"
        self.format = "%(asctime)s %(levelname)-6s %(name)-8s: %(message)s"
        self.root_level = level
        self.production = env.flask == "production"

        if self.production:
            self.handler = RotatingFileHandler(self.file, maxBytes=1000000, backupCount=5)
        else:
            self.handler = logging.StreamHandler()

        self.handler.setLevel(DEBUG)
        self.handler.setFormatter(logging.Formatter(self.format))

    def get_logger(self, name, level):
        if "root" not in self._updated:
            self.config_root()
            self._updated.append("root")

        logger = logging.getLogger(name)
        logger.setLevel(level)

        if name not in self._updated:
            if os.environ.get("WERKZEUG_RUN_MAIN") == "true" or not app.debug:
                logger.addHandler(self.handler)
            self._updated.append(name)

        return logger

    def config_root(self):
        root = logging.getLogger()

        # guarantee that libraries have not set this up already
        for handler in root.handlers[:]:
            root.removeHandler(handler)

        root.setLevel(self.root_level)

        if os.environ.get("WERKZEUG_RUN_MAIN") == "true" or not app.debug:
            root.addHandler(self.handler)

        # Disable propagation to avoid duplicate logs
        root.propagate = False


def logset(name, level=INFO):
    config = LogConfig(DEBUG)  # set the root logging level
    return config.get_logger(name, level)


def log_call(logger):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            logger.debug(f"{func.__name__}({args} {kwargs})")
            result = func(*args, **kwargs)
            logger.debug(f"{func.__name__}() ==> {result}")
            return result

        return wrapper

    return decorator
