"""
    @author : RituRaj
    Date : 23 jan , 2019 
    Updated : 5 feb , 2019
"""

from django.db import models
from rest_framework.generics import ListAPIView, RetrieveAPIView
from rest_framework.views import APIView
try:
    from django.urls import path , re_path
except ImportError:
    from django.conf.urls import include, url

from django.apps import apps

from importlib import import_module
import sys

from .tools import StandardResultsSetPagination

import django
dj_version = django.get_version()

import re


def make_all_viewsets(pathname):
    """Make View sets of Api Views
    
    :param pathname : module path name
    """
    appviews = sys.modules[pathname]
    appname = pathname.split(".")[0]

    app = import_module(appname)
    models = apps.get_app_config(app.__name__).get_models()

    for model in models:
        make_viewset(app, model.__name__, appviews)


def make_viewset(app, class_name, appviews):
    """Create Viewset for models of each app
        Viewset - List Api View , Detail APi View for every models of an app

    :param app: app_name
    :param class_name: model_name  
    :param app_views: app views.py  
    """
    # from demo.api_urls_generated import urlpatterns
    from .autogenerated_urls import urlpatterns
    details_view = make_details_view(app, class_name)
    query_view = make_query_view(app, class_name)

    details_raw_string = '^' + class_name.lower() + '/$'
    if re.search('^2[\d.]+',str(dj_version)):
        urlpatterns.append(re_path(details_raw_string, query_view.as_view()))
    else:
        urlpatterns.append(url(details_raw_string, query_view.as_view()))


    query_raw_string = '^' + class_name.lower() + '/(?P<pk>[0-9]+)/$'
    if re.search('^2[\d.]+',str(dj_version)):
        urlpatterns.append(re_path(query_raw_string, details_view.as_view()))
    else:
        urlpatterns.append(url(query_raw_string, details_view.as_view()))


    setattr(appviews, class_name + "Details", details_view)
    setattr(appviews, class_name + "QueryView", query_view)

def make_details_view(app, class_name):
    """Create DetailApi View
    :param app: app_name
    :ptype app: <django_app> 
    :param class_name: model_name
    :ptype class_name: str

    :return: ApiView - DetailAPiView
    :rtype: restframework api view Class
    """
    klass = getattr(app.models, class_name)
    serializer = getattr(app.serializers, class_name + "DeadlySerializer")
    class DetailsView(RetrieveAPIView):
        queryset = klass.objects.all()
        serializer_class = serializer
        model = klass
        model_app = app
        model_name = class_name
    return DetailsView

def make_query_view(app, class_name, page_class=StandardResultsSetPagination):
    """Create DetailApi View
    :param app: app_name
    :ptype app: <django_app> 
    
    :param class_name: model_name
    :ptype class_name: str
    
    :param page_class: StandardResultsSetPagination Class
    :ptype page_class: rstframework apgination class

    :return: ApiView - QueryAPiView - ListApiView
    :rtype: restframework api view Class
    """
    klass = getattr(app.models, class_name)
    serializer = getattr(app.serializers, class_name + "DeadlySerializer")
    # filter = getattr(app.filters, class_name + "Filter")
    class QueryView(ListAPIView):
        queryset = klass.objects.all()
        serializer_class = serializer
        # FIlter stuff -- update soon
        # filter_class = filter 
        pagination_class = page_class
        model = klass
        model_app = app
        model_name = class_name

        def post(self, request, *args, **kwargs):
            self.queryset = klass.objects.filter(pk__in=request.data)
            return self.list(request, *args, **kwargs)

        def paginate_queryset(self, queryset):
            """Paginate the queryset"""
            if self.paginator is None:
                return None
            if not self.request.query_params.get('paginate'):
                return None
            return self.paginator.paginate_queryset(queryset, self.request, view=self)

    return QueryView



