"""
Author: Michel Peltriaux
Organization: Struktur- und Genehmigungsdirektion Nord, Rhineland-Palatinate, Germany
Contact: michel.peltriaux@sgdnord.rlp.de
Created on: 17.08.21

"""
from django.http import HttpResponse
from django.urls import re_path
from django.views import View
from django.views.decorators.csrf import csrf_exempt
from itsdangerous import TimedSerializer
from simple_sso.sso_client.client import Client

from user.models import User


class PropagateView(View):
    """ View used to receive propagated sso-server user data

    """
    client = None
    signer = None

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.signer = TimedSerializer(self.client.private_key)

    @csrf_exempt
    def dispatch(self, request, *args, **kwargs):
        return super().dispatch(request, *args, **kwargs)

    def post(self, request):
        user_data = request.body
        user_data = self.signer.loads(user_data)
        self.client.build_user(user_data)
        return HttpResponse(status=200)


class KonovaSSOClient(Client):
    """ Konova specialized derivative of general sso.Client.

    Adds some custom behaviour for konova usage.

    """
    propagate_view = PropagateView

    def get_urls(self):
        urls = super().get_urls()
        urls += re_path(r'^propagate/$', self.propagate_view.as_view(client=self), name='simple-sso-propagate'),
        return urls

    def build_user(self, user_data):
        """ Creates a user or updates user data

        Args:
            user_data ():

        Returns:

        """
        try:
            user = User.objects.get(username=user_data['username'])
            # Update user data, excluding some changes
            skipable_attrs = {
                "username",
                "is_staff",
                "is_superuser",
            }
            for _attr, _val in user_data.items():
                if _attr in skipable_attrs:
                    continue
                setattr(user, _attr, _val)
        except User.DoesNotExist:
            user = User(**user_data)
        user.set_unusable_password()
        user.save()
        return user