#
# Copyright 2021 Splunk Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""
Copyright (C) 2005-2019 Splunk Inc. All Rights Reserved.

log utility for TA
"""

import logging
import logging.handlers as handlers
import os.path as op
import time
import warnings

import splunktalib.common.util as cutil
from splunktalib.common.pattern import singleton
from splunktalib.splunk_platform import make_splunkhome_path

logging.Formatter.converter = time.gmtime


def log_enter_exit(logger):
    """
    Log decorator to log function enter and exit
    """
    warnings.warn(
        "This function is deprecated. "
        "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
        DeprecationWarning,
        stacklevel=2,
    )

    def log_decorator(func):
        def wrapper(*args, **kwargs):
            logger.debug("{} entered.".format(func.__name__))
            result = func(*args, **kwargs)
            logger.debug("{} exited.".format(func.__name__))
            return result

        return wrapper

    return log_decorator


@singleton
class Logs:
    def __init__(self, namespace=None, default_level=logging.INFO):
        warnings.warn(
            "This class is deprecated. "
            "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
            DeprecationWarning,
            stacklevel=2,
        )
        self._loggers = {}
        self._default_level = default_level
        if namespace is None:
            namespace = cutil.get_appname_from_path(op.abspath(__file__))

        if namespace:
            namespace = namespace.lower()
        self._namespace = namespace

    def get_logger(self, name, level=None, maxBytes=25000000, backupCount=5):
        """
        Set up a default logger.

        :param name: The log file name.
        :param level: The logging level.
        :param maxBytes: The maximum log file size before rollover.
        :param backupCount: The number of log files to retain.
        """

        # Strip ".py" from the log file name if auto-generated by a script.
        if level is None:
            level = self._default_level

        name = self._get_log_name(name)
        if name in self._loggers:
            return self._loggers[name]

        logfile = make_splunkhome_path(["var", "log", "splunk", name])
        logger = logging.getLogger(name)

        handler_exists = any(
            [True for h in logger.handlers if h.baseFilename == logfile]
        )
        if not handler_exists:
            file_handler = handlers.RotatingFileHandler(
                logfile, mode="a", maxBytes=maxBytes, backupCount=backupCount
            )

            formatter = logging.Formatter(
                "%(asctime)s +0000 log_level=%(levelname)s, pid=%(process)d, tid=%(threadName)s, "
                "file=%(filename)s, func_name=%(funcName)s, code_line_no=%(lineno)d | %(message)s"
            )
            file_handler.setFormatter(formatter)
            logger.addHandler(file_handler)
            logger.setLevel(level)
            logger.propagate = False

        self._loggers[name] = logger
        return logger

    def set_level(self, level, name=None):
        """
        Change the log level of the logging

        :param level: the level of the logging to be setLevel
        :param name: the name of the logging to set, in case it is not set,
                     all the loggers will be affected
        """

        if name is not None:
            name = self._get_log_name(name)
            logger = self._loggers.get(name)
            if logger is not None:
                logger.setLevel(level)
        else:
            self._default_level = level
            for logger in self._loggers.values():
                logger.setLevel(level)

    def _get_log_name(self, name):
        if name.endswith(".py"):
            name = name.replace(".py", "")

        if self._namespace:
            name = "{}_{}.log".format(self._namespace, name)
        else:
            name = "{}.log".format(name)
        return name


# Global logger
logger = Logs().get_logger("util")


def reset_logger(name):
    """
    Reset global logger.
    """
    warnings.warn(
        "This function is deprecated. "
        "Please see https://github.com/splunk/addonfactory-ta-library-python/issues/38",
        DeprecationWarning,
        stacklevel=2,
    )

    global logger
    logger = Logs().get_logger(name)
