##
# Copyright 2019 Telefonica Investigacion y Desarrollo, S.A.U.
# This file is part of OSM
# All Rights Reserved.
#
# 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.
#
# For those usages not covered by the Apache License, Version 2.0 please
# contact with: nfvlabs@tid.es
##


import asyncio
import datetime
import inspect
import logging
import threading  # only for logging purposes (not for using threads)
import time


class Loggable:
    def __init__(self, log, log_to_console: bool = False, prefix: str = ""):
        self._last_log_time = None  # used for time increment in logging
        self._log_to_console = log_to_console
        self._prefix = prefix
        if log is not None:
            self.log = log
        else:
            self.log = logging.getLogger(__name__)

    def debug(self, msg: str):
        self._log_msg(log_level="DEBUG", msg=msg)

    def info(self, msg: str):
        self._log_msg(log_level="INFO", msg=msg)

    def warning(self, msg: str):
        self._log_msg(log_level="WARNING", msg=msg)

    def error(self, msg: str):
        self._log_msg(log_level="ERROR", msg=msg)

    def critical(self, msg: str):
        self._log_msg(log_level="CRITICAL", msg=msg)

    ####################################################################################

    def _log_msg(self, log_level: str, msg: str):
        """Generic log method"""
        msg = self._format_log(
            log_level=log_level,
            msg=msg,
            obj=self,
            level=3,
            include_path=False,
            include_thread=False,
            include_coroutine=True,
        )
        if self._log_to_console:
            print(msg)
        else:
            if self.log is not None:
                if log_level == "DEBUG":
                    self.log.debug(msg)
                elif log_level == "INFO":
                    self.log.info(msg)
                elif log_level == "WARNING":
                    self.log.warning(msg)
                elif log_level == "ERROR":
                    self.log.error(msg)
                elif log_level == "CRITICAL":
                    self.log.critical(msg)

    def _format_log(
        self,
        log_level: str,
        msg: str = "",
        obj: object = None,
        level: int = None,
        include_path: bool = False,
        include_thread: bool = False,
        include_coroutine: bool = True,
    ) -> str:
        # time increment from last log
        now = time.perf_counter()
        if self._last_log_time is None:
            time_str = " (+0.000)"
        else:
            diff = round(now - self._last_log_time, 3)
            time_str = " (+{})".format(diff)
        self._last_log_time = now

        if level is None:
            level = 1

        # stack info
        fi = inspect.stack()[level]
        filename = fi.filename
        func = fi.function
        lineno = fi.lineno
        # filename without path
        if not include_path:
            i = filename.rfind("/")
            if i > 0:
                filename = filename[i + 1 :]

        # datetime
        dt = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
        dt = dt + time_str
        # dt = time_str       # logger already shows datetime

        # current thread
        if include_thread:
            thread_name = "th:{}".format(threading.current_thread().getName())
        else:
            thread_name = ""

        # current coroutine

        coroutine_id = ""
        if include_coroutine:
            try:
                if asyncio.Task.current_task() is not None:

                    def print_cor_name(c):
                        import inspect

                        try:
                            for m in inspect.getmembers(c):
                                if m[0] == "__name__":
                                    return m[1]
                        except Exception:
                            pass

                    coro = asyncio.Task.current_task()._coro
                    coroutine_id = "coro-{} {}()".format(
                        hex(id(coro))[2:], print_cor_name(coro)
                    )
            except Exception:
                coroutine_id = ""

        # classname
        if obj is not None:
            obj_type = obj.__class__.__name__  # type: str
            log_msg = "{} {} {} {} {}::{}.{}():{}\n{}".format(
                self._prefix,
                dt,
                thread_name,
                coroutine_id,
                filename,
                obj_type,
                func,
                lineno,
                str(msg),
            )
        else:
            log_msg = "{} {} {} {} {}::{}():{}\n{}".format(
                self._prefix,
                dt,
                thread_name,
                coroutine_id,
                filename,
                func,
                lineno,
                str(msg),
            )

        return log_msg
