#
# Aura Engine API (https://gitlab.servus.at/aura/engine-api)
#
# Copyright (C) 2020 - The Aura Engine Team.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


import logging


class AuraLogger:
    """
    AuraLogger Class

    Logger for all Aura Engine components. The default
    logger is `AuraEngine`. Other loggers are defined
    by passing a custom name on instantiation.

    The logger respects the log-level as defined in the
    engine's configuration file.
    """

    config = None
    logger = None

    def __init__(self, config, name="engine-api"):
        """
        Constructor to create a new logger defined by
        the passed name.

        Args:
            name (String):  The name of the logger
        """
        self.config = config
        self.create_logger(name)

    def get_log_level(self):
        """
        Retrieve the configured log level (default=INFO).
        """
        lvl = self.config.get("loglevel")
        mapping = {
            "debug": logging.DEBUG,
            "info": logging.INFO,
            "warning": logging.WARNING,
            "error": logging.ERROR,
            "critical": logging.CRITICAL,
        }

        log_level = mapping.get(lvl)
        if not log_level:
            print("No log level configured. Using INFO.")
            log_level = logging.INFO
        print(f"Setting log level {log_level} ({lvl})")
        return log_level

    def create_logger(self, name):
        """
        Creates the logger instance for the given name.

        Args:
            name (String):  The name of the logger
        """
        lvl = self.get_log_level()

        # create logger
        self.logger = logging.getLogger(name)
        self.logger.setLevel(lvl)

        if not self.logger.hasHandlers():
            # create file handler for logger
            file_path = self.config.get("logdir") + "/" + name + ".log"
            file_handler = logging.FileHandler(file_path)
            file_handler.setLevel(lvl)

            # create stream handler for logger
            stream_handler = logging.StreamHandler()
            stream_handler.setLevel(lvl)

            # set format of log
            datepart = "%(asctime)s:%(name)s:%(levelname)s"
            message = " - %(message)s - "
            filepart = "[%(filename)s:%(lineno)s-%(funcName)s()]"
            formatter = logging.Formatter(datepart + message + filepart)

            # set log of handlers
            file_handler.setFormatter(formatter)
            stream_handler.setFormatter(formatter)

            # add handlers to the logger
            self.logger.addHandler(file_handler)
            self.logger.addHandler(stream_handler)
            self.logger.debug("Added handlers to logger")
        else:
            self.logger.debug("Reused logger")