#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Pearson Service Insight's Logging API Module
This module contains a class with methods to interact with the Logging API.
"""
from __future__ import annotations

import json
import logging

from functools import wraps
from os import environ
from sys import stdout
from typing import Any


class Logger:
    def __init__(
        self,
        name: str = 'psi-logger',
        level: str = None,
        logger: logging.Logger = None
    ) -> None:

        formatter = logging.Formatter(
            "%(asctime)s [%(levelname)s] [%(filename)s:%(lineno)d] %(message)s"
        )

        self._level = level or environ.get('LOG_LEVEL', 'debug')

        handler = logging.StreamHandler(stdout)
        handler.setFormatter(formatter)

        self._log = logger or logging.getLogger(name)
        self._log.addHandler(handler)
        self._log.propagate = False
        self._set_level(level=self._level)

    def _set_level(self, level: str = 'debug') -> None:
        level = level.lower()
        if level == 'info':
            level = logging.INFO
        elif level == 'warning':
            level = logging.WARNING
        elif level == 'error':
            level = logging.ERROR
        elif level == 'critical':
            level = logging.CRITICAL
        elif level == 'none':
            level = logging.NOTSET
        else:
            level = logging.DEBUG
        self._log.setLevel(level)

    def log_it(self, func) -> None:
        @wraps(func)
        def __call__(*args, **kwargs):
            self._log.debug(
                f'-- {func.__module__}.{func.__qualname__}(args={args},kwargs={kwargs} --'
            )
            return func(*args, **kwargs)
        return __call__

    def __repr__(self) -> str:
        """Return a string representation of the object"""
        return f"{type(self)}"

    def get_logger(self) -> logging.Logger:
        return self._log

    def toJSON(self) -> str:
        return json.dumps(self, default=lambda o: o.__dict__,
                          sort_keys=True, indent=2)

    def __getitem__(self, key) -> Any:
        return self.__getattribute__(key)

    def check(self):
        return {'OK': True}
