#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import os
import logging
import json
from pathlib import Path
from django.http import HttpRequest

BUILDDIR = Path(os.environ.get('BUILDDIR', '/tmp'))

def log_api_request(request, response, view, logger_name='api'):
    """Helper function for LogAPIMixin"""

    repjson = {
        'view': view,
        'path': request.path,
        'method': request.method,
        'status': response.status_code
    }

    logger = logging.getLogger(logger_name)
    logger.info(
        json.dumps(repjson, indent=4, separators=(", ", " : "))
    )


def log_view_mixin(view):
    def log_view_request(*args, **kwargs):
        # get request from args else kwargs
        request = None
        if len(args) > 0:
            for req in args:
                if isinstance(req, HttpRequest):
                    request = req
                    break 
        elif request is None:
            request = kwargs.get('request')

        response = view(*args, **kwargs)
        view_name = 'unknown'
        if hasattr(request, 'resolver_match'):
            if hasattr(request.resolver_match, 'view_name'):
                view_name = request.resolver_match.view_name

        log_api_request(
            request, response, view_name, 'toaster')
        return response
    return log_view_request



class LogAPIMixin:
    """Logs API requests

    tested with:
        - APIView
        - ModelViewSet
        - ReadOnlyModelViewSet
        - GenericAPIView

    Note: you can set `view_name` attribute in View to override get_view_name()
    """

    def get_view_name(self):
        if hasattr(self, 'view_name'):
            return self.view_name
        return super().get_view_name()

    def finalize_response(self, request, response, *args, **kwargs):
        log_api_request(request, response, self.get_view_name())
        return super().finalize_response(request, response, *args, **kwargs)


LOGGING_SETTINGS = {
    'version': 1,
    'disable_existing_loggers': False,
    'filters': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'formatters': {
        'datetime': {
            'format': '%(asctime)s %(levelname)s %(message)s'
        },
        'verbose': {
            'format': '{levelname} {asctime} {module} {name}.{funcName} {process:d} {thread:d} {message}',
            'datefmt': "%d/%b/%Y %H:%M:%S",
            'style': '{',
        },
        'api': {
            'format': '\n{levelname} {asctime} {name}.{funcName}:\n{message}',
            'style': '{'
        }
    },
    'handlers': {
        'mail_admins': {
            'level': 'ERROR',
            'filters': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        },
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'datetime',
        },
        'file_django': {
            'level': 'INFO',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': BUILDDIR / 'toaster_logs/django.log',
            'when': 'D',  # interval type
            'interval': 1,  # defaults to 1
            'backupCount': 10,  # how many files to keep
            'formatter': 'verbose',
        },
        'file_api': {
            'level': 'INFO',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': BUILDDIR / 'toaster_logs/api.log',
            'when': 'D',
            'interval': 1,
            'backupCount': 10,
            'formatter': 'verbose',
        },
        'file_toaster': {
            'level': 'INFO',
            'class': 'logging.handlers.TimedRotatingFileHandler',
            'filename': BUILDDIR / 'toaster_logs/web.log',
            'when': 'D',
            'interval': 1,
            'backupCount': 10,
            'formatter': 'verbose',
        },
    },
    'loggers': {
        'django.request': {
            'handlers': ['file_django', 'console'],
            'level': 'WARN',
            'propagate': True,
        },
        'django': {
            'handlers': ['file_django', 'console'],
            'level': 'WARNING',
            'propogate': True,
        },
        'toaster': {
            'handlers': ['file_toaster'],
            'level': 'INFO',
            'propagate': False,
        },
        'api': {
            'handlers': ['file_api'],
            'level': 'INFO',
            'propagate': False,
        }
    }
}
