from django.contrib.auth.signals import user_logged_in, user_logged_out
from django.utils import timezone
from rest_framework import status
from rest_framework.permissions import IsAuthenticated
from rest_framework.response import Response
from rest_framework.serializers import DateTimeField
from rest_framework.settings import api_settings
from rest_framework.views import APIView

from knox.auth import TokenAuthentication
from knox.models import AuthToken
from knox.settings import knox_settings


class LoginView(APIView):
    authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
    permission_classes = (IsAuthenticated,)

    def get_context(self):
        return {'request': self.request, 'format': self.format_kwarg, 'view': self}

    def get_token_ttl(self):
        return knox_settings.TOKEN_TTL

    def get_token_limit_per_user(self):
        return knox_settings.TOKEN_LIMIT_PER_USER

    def get_user_serializer_class(self):
        return knox_settings.USER_SERIALIZER

    def get_expiry_datetime_format(self):
        return knox_settings.EXPIRY_DATETIME_FORMAT

    def post(self, request, format=None):
        token_limit_per_user = self.get_token_limit_per_user()
        if token_limit_per_user is not None:
            now = timezone.now()
            token = request.user.auth_token_set.filter(expiry__gt=now)
            if token.count() >= token_limit_per_user:
                return Response(
                    {"error": "Maximum amount of tokens allowed per user exceeded."},
                    status=status.HTTP_403_FORBIDDEN
                )
        token_ttl = self.get_token_ttl()
        instance, token = AuthToken.objects.create(request.user, token_ttl)
        user_logged_in.send(sender=request.user.__class__,
                            request=request, user=request.user)
        UserSerializer = self.get_user_serializer_class()
        datetime_format = self.get_expiry_datetime_format()

        data = {
            'expiry': DateTimeField(
                format=datetime_format).to_representation(instance.expiry),
            'token': token
        }
        if UserSerializer is not None:
            data["user"] = UserSerializer(
                request.user,
                context=self.get_context()
            ).data
        return Response(data)


class LogoutView(APIView):
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def post(self, request, format=None):
        request._auth.delete()
        user_logged_out.send(sender=request.user.__class__,
                             request=request, user=request.user)
        return Response(None, status=status.HTTP_204_NO_CONTENT)


class LogoutAllView(APIView):
    '''
    Log the user out of all sessions
    I.E. deletes all auth tokens for the user
    '''
    authentication_classes = (TokenAuthentication,)
    permission_classes = (IsAuthenticated,)

    def post(self, request, format=None):
        request.user.auth_token_set.all().delete()
        user_logged_out.send(sender=request.user.__class__,
                             request=request, user=request.user)
        return Response(None, status=status.HTTP_204_NO_CONTENT)

@@ -1093,16 +1093,642 @@
 FORMAT%0A%0A
+    def format_expiry_datetime(self, expiry):%0A        datetime_format = self.get_expiry_datetime_format()%0A        return DateTimeField(format=datetime_format).to_representation(expiry)%0A%0A    def get_post_response_data(self, request, token, instance):%0A        UserSerializer = self.get_user_serializer_class()%0A%0A        data = %7B%0A            'expiry': self.format_expiry_datetime(instance.expiry),%0A            'token': token%0A        %7D%0A        if UserSerializer is not None:%0A            data%5B%22user%22%5D = UserSerializer(%0A                request.user,%0A                context=self.get_context()%0A            ).data%0A        return data%0A%0A
     def 
@@ -2469,459 +2469,68 @@
     
-UserSerializer = self.get_user_serializer_class()%0A        datetime_format = self.get_expiry_datetime_format()%0A%0A        data = %7B%0A            'expiry': DateTimeField(%0A                format=datetime_format).to_representation(instance.expiry),%0A            'token': token%0A        %7D%0A        if UserSerializer is not None:%0A            data%5B%22user%22%5D = UserSerializer(%0A                request.user,%0A                context=self.get_context()%0A            ).data
+data = self.get_post_response_data(request, token, instance)
 %0A   

Add method to cutomize the post response data