import traceback
import logging.config
import sys

from path import Path
import yaml

from core.constants import LOG_DIR, LOGGER_NAME, LOGGER_LEVEL

SYS_EXCEPT_HOOK = sys.excepthook


class Logger:
    _current = None

    @staticmethod
    def get():
        if Logger._current is None:
            configfile = Path(__file__).parent
            with open(configfile / 'logging.yaml', 'rt') as f:
                conf = yaml.load(f, Loader=yaml.FullLoader)

            conf["loggers"][LOGGER_NAME]["level"] = LOGGER_LEVEL

            filename = LOG_DIR / f'{LOGGER_NAME}.log'
            conf["handlers"]["file"]["filename"] = filename

            logging.config.dictConfig(conf)

            logger = logging.getLogger(LOGGER_NAME)

            # Configure how errors are processed
            sys_err = sys.excepthook

            def err_handler(typ, value, trace):
                logger.error("{}\n{}\n{}".format(typ.__name__, value, ''.join(traceback.format_tb(trace))))
                sys_err(typ, value, trace)

            sys.excepthook = err_handler

            Logger._current = logger

        return Logger._current
