"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: ksp-servicestelle@sgdnord.rlp.de
Created on: 11.12.23

"""
import json
from json import JSONDecodeError

from django.views.debug import ExceptionReporter


class KonovaExceptionReporter(ExceptionReporter):
    """ Custom exception reporter class

    Adapts the base functionality of ExceptionReporter but adds whitelist filtering to prevent sensitive data
    to be exploitable via mail delivery.

    References:
    https://docs.djangoproject.com/en/4.2/ref/logging/#handlers

    """

    def _filter_traceback_data(self, tb_data: dict):
        """ Filters given traceback data according to whitelist

        Args:
            tb_data (dict): Aggregates traceback data

        Returns:
            clean_data (dict): Whitelist based filtered traceback data
        """
        whitelist = [
            "is_email",
            "unicode_hint",
            "frames",
            "request",
            "user_str",
            "sys_executable",
            "sys_version_info",
            "raising_view_name",
            "exception_type",
            "exception_value",
            "filtered_GET_items",
            "filtered_POST_items",
        ]
        clean_data = dict()
        for entry in whitelist:
            try:
                clean_data[entry] = tb_data[entry]
            except KeyError:
                continue
        return clean_data

    def get_traceback_data(self):
        """ Custom traceback data aggregation

        Returns:
            tb_data (dict): The traceback data
        """
        tb_data = super().get_traceback_data()

        return_data = tb_data
        if self.is_email:
            filtered_data = dict()
            filtered_data.update(self._filter_traceback_data(tb_data))
            filtered_data.update(self._filter_POST_body(tb_data))
            return_data = filtered_data
        return return_data

    def _filter_POST_body(self, tb_data: dict):
        """ Filters POST body from traceback data

        """
        post_data = tb_data.get("request", None)
        if post_data:
            post_data = post_data.body
            try:
                post_data = json.loads(post_data)
            except JSONDecodeError:
                pass
        post_data = {
            "filtered_POST_items": [
                ("body", post_data),
            ]
        }
        return post_data