import pytest
from django.urls import reverse
from rest_framework import status
from rest_framework.test import APIClient

from rotation.enums import RotationType
from rotation.models import EventRotationSettings

api_client = APIClient()


@pytest.mark.django_db
class TestRotationAPI:

    @pytest.mark.unit
    def test_save_and_update_event_rotation_settings(self, add_user_with_permissions):
        user = add_user_with_permissions(username='test_admin', password='pwdadmin', is_superuser=True)
        api_client.force_authenticate(user)
        url = reverse('event-schedule-set')

        data = {
            "rotation_type": 1,
            "size_rotation": 65432
        }
        response = api_client.post(url, data=data, format='json')

        assert response.status_code == status.HTTP_200_OK
        assert response.data == {'rotation_type': 1, 'size_rotation': 65432}

        rotate_settings = EventRotationSettings.get_solo()
        rotate_settings.clear_cache()

        assert rotate_settings.rotation_type == RotationType.SIZE
        assert rotate_settings.size_rotation == data['size_rotation']

    @pytest.mark.unit
    def test_rotation_doesnt_update_with_invalid_data(self, add_user_with_permissions):
        user = add_user_with_permissions(username='test_admin', password='pwdadmin', is_superuser=True)
        api_client.force_authenticate(user)
        url = reverse('event-schedule-set')
        rotate_settings = EventRotationSettings.get_solo()
        old_type = rotate_settings.rotation_type
        old_size = rotate_settings.size_rotation
        rotate_settings.clear_cache()

        data = {
            "rotation_type": 1,
            "size_rotation": 'bad'
        }
        response = api_client.post(url, data=data, format='json')

        assert response.status_code == status.HTTP_400_BAD_REQUEST
        assert 'size_rotation' in response.data
        assert len(response.data) == 1  # only one error in response

        rotate_settings = EventRotationSettings.get_solo()
        assert rotate_settings.rotation_type == old_type
        assert rotate_settings.size_rotation == old_size

        # test negative size
        data = {
            "rotation_type": 1,
            "size_rotation": -1
        }
        response = api_client.post(url, data=data, format='json')

        assert response.status_code == status.HTTP_400_BAD_REQUEST
        assert 'size_rotation' in response.data
        assert len(response.data) == 1  # only one error in response

        rotate_settings = EventRotationSettings.get_solo()
        assert rotate_settings.rotation_type == old_type
        assert rotate_settings.size_rotation == old_size

    @pytest.mark.unit
    def test_rotation_doesnt_update_with_invalid_data_type(self, add_user_with_permissions):
        """Checking that when submitting data in non-json format , we return 400 and not 500"""
        user = add_user_with_permissions(username='test_admin', password='pwdadmin', is_superuser=True)
        api_client.force_authenticate(user)
        url = reverse('event-schedule-set')
        rotate_settings = EventRotationSettings.get_solo()
        old_type = rotate_settings.rotation_type
        old_size = rotate_settings.size_rotation
        rotate_settings.clear_cache()

        data = {
            "rotation_type": 1,
            "size_rotation": 50
        }
        response = api_client.post(url, data=data)
        assert response.status_code == status.HTTP_400_BAD_REQUEST
        rotate_settings = EventRotationSettings.get_solo()
        assert rotate_settings.rotation_type == old_type
        assert rotate_settings.size_rotation == old_size

        # test negative size
        data = {
            "rotation_type": 1,
            "size_rotation": -1
        }
        response = api_client.post(url, data=data, format='json')

        assert response.status_code == status.HTTP_400_BAD_REQUEST
        assert 'size_rotation' in response.data
        assert len(response.data) == 1  # only one error in response

        rotate_settings = EventRotationSettings.get_solo()
        assert rotate_settings.rotation_type == old_type
        assert rotate_settings.size_rotation == old_size

    @pytest.mark.unit
    def test_save_and_update_incident_rotation_settings(self, add_user_with_permissions):
        user = add_user_with_permissions(username='test_admin', password='pwdadmin', is_superuser=True)
        api_client.force_authenticate(user)
        url = reverse('incident-schedule-set')

        data = {
            "rotation_type": 0,
            "schedule": {
                "period": "day",
                "time": "22:22:00",
            }
        }
        response = api_client.post(url, data=data, format='json')

        assert response.status_code == status.HTTP_200_OK
        assert response.json() == {
            'rotation_type': 0,
            'schedule': {
                'month': [],
                'period': 'day',
                'time': "22:22:00",
                'week_day': []
            },
            'size_rotation': 5242880
        }

        current_settings_url = reverse('incident-schedule-current-settings')
        response_data = api_client.get(current_settings_url).json()
        assert response_data['rotation_type'] == RotationType.TIME
        assert response_data['schedule']['period'] == data['schedule']['period']
        assert response_data['schedule']['time'] == data['schedule']['time']
