"""Module for a json formatted logger"""

import logging

import datetime as dt

from pythonjsonlogger import jsonlogger


def get_logger(name: str) -> logging.Logger:
    """Returns logger instance"""
    logging.captureWarnings(True)
    logger = logging.getLogger(name)
    logger.setLevel(logging.DEBUG)
    if not logger.hasHandlers():
        handler = logging.StreamHandler()
        handler.setFormatter(
            logging.Formatter(
                '[%(asctime)s] %(threadName)s %(name)s'
                ' [%(levelname)7s] %(message)s'
            )
        )
        logger.addHandler(handler)
    return logger


def get_logger_json(name: str = 'logger'):
    """Function to get a new logger instance"""
    log = logging.getLogger(name)
    log.setLevel(logging.INFO)
    if not log.handlers:
        log.addHandler(get_app_logging_handler())
    return log


def get_app_logging_handler() -> logging.StreamHandler:
    """Getting a new logging handler"""
    log_handler = logging.StreamHandler()
    formatter = JsonLogFormatter()
    log_handler.setFormatter(formatter)
    return log_handler


class JsonLogFormatter(jsonlogger.JsonFormatter):
    """Json Log formatter following the Zooplus standards."""

    def add_fields(
            self,
            log_record: dict,
            record: logging.LogRecord,
            message_dict: dict) -> None:
        super().add_fields(log_record, record, message_dict)

        log_record['log_type'] = 'application_log'
        log_record['@timestamp'] = dt.datetime.now(dt.timezone.utc).isoformat()
        log_record['description'] = log_record.pop('message', None)
        log_record['severity'] = record.levelname.upper()
        log_record['class'] = ':'.join(
            [record.module, record.funcName, str(record.lineno)]
        )

        if exc_info := log_record.pop('exc_info', None):
            log_record['stacktrace'] = exc_info
        if record.process:
            log_record['pid'] = record.process
        if record.threadName:
            log_record['thread'] = record.threadName
