"""
This submodule exports `logger` to log events.

Logging messages which are less severe than `lvl` will be ignored

Level       Numeric value
-----       -------------
CRITICAL    50
ERROR       40
WARNING     30
INFO        20
DEBUG       10
NOTSET      0

Level       When it’s used
-----       --------------
DEBUG       Detailed information, typically of interest only when diagnosing
                problems.
INFO        Confirmation that things are working as expected.
WARNING     An indication that something unexpected happened, or indicative of
                some problem in the near future (e.g. ‘disk space low’).
                The software is still working as expected.
ERROR       Due to a more serious problem, the software has not been able to
                perform some function.
CRITICAL	A serious error, indicating that the program itself may be unable
                to continue running.
"""

import logging
from functools import wraps

from logging.config import dictConfig

logging.getLogger(__name__).addHandler(logging.NullHandler())

log_format = """\
%(levelname)s:%(filename)s,%(lineno)s:%(funcName)s() %(message)s\
"""

date_format = '%Y/%m/%d,%H:%M:%S'

logging_config = dict(
    version=1,
    formatters={
        'f': {
             'format': log_format,
             'datefmt': date_format,
        }
    },
    handlers={
        'h': {
                'class': 'logging.StreamHandler',
                'formatter': 'f',
                'level': logging.DEBUG,
        }
    },
    root={
        'handlers': ['h'],
        'level': logging.WARNING,
    },
)

dictConfig(logging_config)

logger = logging.getLogger()


def log_event(f, *args, **kwargs):

    @wraps(f)
    def decorator(*args, **kwargs):

        # arguments = str(args) # 0 is self
        # kw_arguments = str(kwargs)
        qname = f.__qualname__

        arguments = ', '.join([repr(arg) for arg in args])  # 0 is self
        kw_arguments = ', '.join(['{}={}'.format(k, repr(v))
                                 for k, v in kwargs.items()])

        if logger.isEnabledFor(logging.INFO):
            logger.info("{qname}() called.".format(qname=qname))

        if logger.isEnabledFor(logging.DEBUG):
            # logger.debug("\t*{}, **{}".format(
            # arguments, kw_arguments).expandtabs())
            logger.debug("{qname}({args}, {kwargs})".
                         format(qname=qname, args=arguments,
                                kwargs=kw_arguments). expandtabs())

            # init returns the very own object
            if f.__name__ != '__init__':

                func_return = f(*args, **kwargs)
                logger.debug("{qname} function returned: '{func_ret}'".
                             format(qname=qname, func_ret=func_return))

                return func_return

        return f(*args, **kwargs)

    # RESOLUTION_METHODS.update({f.__name__: f})

    return decorator
