"""
This file contains the viewsets (based on the elsewhere defined data models and serializers)
"""

from django.shortcuts import get_object_or_404
from rest_framework import viewsets
from .lofar_viewset import LOFARViewSet
from .. import models
from .. import serializers
from django_filters import rest_framework as filters
from lofar.sas.tmss.tmss.tmssapp.models.scheduling import Subtask
# Don't use Ordering class from the django_filters but use rest_framework instead !!
from rest_framework.filters import OrderingFilter


class subTaskFilter(filters.FilterSet):
    class Meta:
        model = Subtask
        fields = {
            'state__value': ['exact'],
            'start_time': ['lt', 'gt'],
            'stop_time': ['lt', 'gt'],
            'cluster__name': ['exact', 'icontains'],
        }

from rest_framework.decorators import action
from django.http import HttpResponse, JsonResponse
from drf_yasg.utils import swagger_auto_schema

from lofar.sas.tmss.tmss.tmssapp.viewsets.lofar_viewset import LOFARViewSet
from lofar.sas.tmss.tmss.tmssapp import models
from lofar.sas.tmss.tmss.tmssapp import serializers

from lofar.common.json_utils import get_default_json_object_for_schema
from lofar.sas.tmss.tmss.tmssapp.adapters.parset import convert_to_parset


class SubtaskConnectorViewSet(LOFARViewSet):
    queryset = models.SubtaskConnector.objects.all()
    serializer_class = serializers.SubtaskConnectorSerializer


class SubtaskStateViewSet(LOFARViewSet):
    queryset = models.SubtaskState.objects.all()
    serializer_class = serializers.SubtaskStateSerializer


class SubtaskTypeViewSet(LOFARViewSet):
    queryset = models.SubtaskType.objects.all()
    serializer_class = serializers.SubtaskTypeSerializer


class StationTypeViewSet(LOFARViewSet):
    queryset = models.StationType.objects.all()
    serializer_class = serializers.StationTypeSerializer


class AlgorithmViewSet(LOFARViewSet):
    queryset = models.Algorithm.objects.all()
    serializer_class = serializers.AlgorithmSerializer


class ScheduleMethodViewSet(LOFARViewSet):
    queryset = models.ScheduleMethod.objects.all()
    serializer_class = serializers.ScheduleMethodSerializer


class SubtaskTemplateViewSet(LOFARViewSet):
    queryset = models.SubtaskTemplate.objects.all()
    serializer_class = serializers.SubtaskTemplateSerializer

    def get_queryset(self):
        queryset = models.SubtaskTemplate.objects.all()

        # query by name
        name = self.request.query_params.get('name', None)
        if name is not None:
            return queryset.filter(name=name)

        return queryset

    @swagger_auto_schema(responses={200: 'JSON object with all the defaults from the schema filled in',
                                    403: 'forbidden'},
                         operation_description="Get a JSON object with all the defaults from the schema filled in.")
    @action(methods=['get'], detail=True)
    def default_specification(self, request, pk=None):
        subtask_template = get_object_or_404(models.SubtaskTemplate, pk=pk)
        spec = get_default_json_object_for_schema(subtask_template.schema)
        return JsonResponse(spec)


class DefaultSubtaskTemplateViewSet(LOFARViewSet):
    queryset = models.DefaultSubtaskTemplate.objects.all()
    serializer_class = serializers.DefaultSubtaskTemplateSerializer


class DataproductSpecificationsTemplateViewSet(LOFARViewSet):
    queryset = models.DataproductSpecificationsTemplate.objects.all()
    serializer_class = serializers.DataproductSpecificationsTemplateSerializer


class DefaultDataproductSpecificationsTemplateViewSet(LOFARViewSet):
    queryset = models.DefaultDataproductSpecificationsTemplate.objects.all()
    serializer_class = serializers.DefaultDataproductSpecificationsTemplateSerializer


class SubtaskInputSelectionTemplateViewSet(LOFARViewSet):
    queryset = models.SubtaskInputSelectionTemplate.objects.all()
    serializer_class = serializers.SubtaskInputSelectionTemplateSerializer


class DataproductFeedbackTemplateViewSet(LOFARViewSet):
    queryset = models.DataproductFeedbackTemplate.objects.all()
    serializer_class = serializers.DataproductFeedbackTemplateSerializer


class SubtaskViewSet(LOFARViewSet):
    queryset = models.Subtask.objects.all()
    serializer_class = serializers.SubtaskSerializer
    filter_backends = (filters.DjangoFilterBackend,)
    filter_class = subTaskFilter

    def get_queryset(self):
        if 'task_blueprint_pk' in self.kwargs:
            task_blueprint = get_object_or_404(models.TaskBlueprint, pk=self.kwargs['task_blueprint_pk'])
            return task_blueprint.subtasks.all()
        else:
            return models.Subtask.objects.all()

    @swagger_auto_schema(responses={200: 'A LOFAR parset for this subtask',
                                    403: 'forbidden'},
                         operation_description="Get a a LOFAR parset for the specifications of this subtask")
    @action(methods=['get'], detail=True)
    def default_specification(self, request, pk=None):
        subtask = get_object_or_404(models.Subtask, pk=pk)
        parset = convert_to_parset(subtask)
        return HttpResponse(str(parset), content_type='text/plain')

class SubtaskInputViewSet(LOFARViewSet):
    queryset = models.SubtaskInput.objects.all()
    serializer_class = serializers.SubtaskInputSerializer


class SubtaskOutputViewSet(LOFARViewSet):
    queryset = models.SubtaskOutput.objects.all()
    serializer_class = serializers.SubtaskOutputSerializer


class DataproductViewSet(LOFARViewSet):
    queryset = models.Dataproduct.objects.all()
    serializer_class = serializers.DataproductSerializer


class AntennaSetViewSet(LOFARViewSet):
    queryset = models.AntennaSet.objects.all()
    serializer_class = serializers.AntennaSetSerializer


class DataproductTransformViewSet(LOFARViewSet):
    queryset = models.DataproductTransform.objects.all()
    serializer_class = serializers.DataproductTransformSerializer


class FilesystemViewSet(LOFARViewSet):
    queryset = models.Filesystem.objects.all()
    serializer_class = serializers.FilesystemSerializer


class ClusterViewSet(LOFARViewSet):
    queryset = models.Cluster.objects.all()
    serializer_class = serializers.ClusterSerializer


class DataproductArchiveInfoViewSet(LOFARViewSet):
    queryset = models.DataproductArchiveInfo.objects.all()
    serializer_class = serializers.DataproductArchiveInfoSerializer


class DataproductHashViewSet(LOFARViewSet):
    queryset = models.DataproductHash.objects.all()
    serializer_class = serializers.DataproductHashSerializer


# --- JSON

class SubtaskViewSetJSONeditorOnline(LOFARViewSet):
     queryset = models.Subtask.objects.all()
     serializer_class = serializers.SubtaskSerializerJSONeditorOnline
     filter_backends = (filters.DjangoFilterBackend, OrderingFilter,)
     filter_class = subTaskFilter
     ordering = ('start_time',)

     def get_view_name(self):   # override name because DRF auto-naming dot_tmssapp_scheduling_djangoes not produce something usable here
        name = "Subtask"
        if self.suffix:
            name += ' ' + self.suffix
        return name

     def get_queryset(self):
         if 'task_blueprint_pk' in self.kwargs:
             task_blueprint = get_object_or_404(models.TaskBlueprint, pk=self.kwargs['task_blueprint_pk'])
             return task_blueprint.subtasks.all()
         else:
             return models.Subtask.objects.all()

     @swagger_auto_schema(responses={200: 'A LOFAR parset for this subtask (as plain text, not json)',
                                     403: 'forbidden',
                                     404: 'Not found'},
                          operation_description="Get a LOFAR parset for the specifications of this subtask")
     @action(methods=['get'], detail=True)
     def parset(self, request, pk=None):
         subtask = get_object_or_404(models.Subtask, pk=pk)
         parset = convert_to_parset(subtask)
         return HttpResponse(str(parset), content_type='text/plain')