import logging

from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.viewsets import ViewSet

from console import conslog
from core.mixins import ApiPermissionCheckMixin
from perms.models import Perm
from rotation.enums import RotationType
from rotation.models import IncidentRotationSettings, EventRotationSettings
from rotation.serializers import RotationSettingsSerializer, SizeRotationSettingsSerializer, \
    TimeRotationSettingsSerializer, FullRotationSettingsSerializer
from rotation.services.update_schedule import update_model_with_data

_log = logging.getLogger(__name__)


class ScheduleUpdateViewSetMixin(ViewSet):
    """
        A mixin that adds two actions to set up a rotation.
        Used when setting up the rotation of incidents and events.
    """

    @property
    def serializer_class(self):
        if self.request.data.get('rotation_type') == RotationType.SIZE:
            return SizeRotationSettingsSerializer
        elif self.request.data.get('rotation_type') == RotationType.TIME:
            return TimeRotationSettingsSerializer
        return RotationSettingsSerializer

    @action(detail=False, name='set', methods=['POST'])
    def set(self, request):
        conslog.add_info_log(conslog.url_access_log(request), _log)
        serializer = self.serializer_class(data=request.data)
        if serializer.is_valid():
            try:
                settings_obj = update_model_with_data(serializer, self.settings_class, self.type, self.task_name)
                settings_data = FullRotationSettingsSerializer(instance=settings_obj).data
                return Response(settings_data, status.HTTP_200_OK)
            except KeyError:
                return Response("Bad request data format", status.HTTP_400_BAD_REQUEST)

        return Response(status=status.HTTP_400_BAD_REQUEST, data=serializer.errors)

    @action(methods=['GET'], detail=False)
    def current_settings(self, request, *args, **kwargs):
        settings_obj = self.settings_class.get_solo()
        settings_data = FullRotationSettingsSerializer(instance=settings_obj).data
        return Response(settings_data, status.HTTP_200_OK)


class IncidentRotationUpdateViewSet(ApiPermissionCheckMixin, ScheduleUpdateViewSetMixin):
    settings_class = IncidentRotationSettings
    type = 'incidents'
    task_name = 'rotation.tasks.rotate_incidents'
    console_permissions = [Perm.can_change_rotation_settings]


class EventRotationUpdateViewSet(ApiPermissionCheckMixin, ScheduleUpdateViewSetMixin):
    settings_class = EventRotationSettings
    type = 'events'
    task_name = 'rotation.tasks.rotate_elasticsearch'
    console_permissions = [Perm.can_change_rotation_settings]
