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

from incident_export.enums import ReceiverType, SysLogSendProtocol
from incident_export.models import SyslogReceiver, OpcuaReceiver, Receiver

client = APIClient()


@pytest.mark.django_db
class TestApi(object):

    @pytest.fixture(autouse=True)
    def testing_incident_export_api(self, django_user_model, add_user_with_permissions):
        self.admin = django_user_model.objects.first()

        for i in range(0, 5):
            syslog_receiver_instance = Receiver.objects.create(type=ReceiverType.SYSLOG, export_status=True)
            SyslogReceiver.objects.create(receiver=syslog_receiver_instance,
                                          protocol=SysLogSendProtocol.UDP,
                                          host=f'1.0.0.{i}',
                                          port='514')
            opcua_receiver_instance = Receiver.objects.create(type=ReceiverType.OPCUA,
                                                              export_status=True)
            OpcuaReceiver.objects.create(receiver=opcua_receiver_instance,
                                         host=f'127.0.0.{i}',
                                         port='123',
                                         node_number='50')

    @pytest.mark.unit
    def test_creating_syslog_receiver(self):
        syslog_url = reverse('export_syslog_receivers-list')

        client.force_authenticate(self.admin)

        data = {
            "receiver": {
                "type": ReceiverType.SYSLOG
            },
            "host": "1.1.1.1",
            "port": 1,
            "protocol": SysLogSendProtocol.UDP
        }
        response = client.post(syslog_url, data=data, format='json')
        assert response.status_code == status.HTTP_201_CREATED

        new_receiver_id = response.data['id']
        assert SyslogReceiver.objects.filter(id=new_receiver_id).exists()

    @pytest.mark.unit
    def test_creating_syslog_receiver_with_invalid_data(self):
        syslog_url = reverse('export_syslog_receivers-list')

        client.force_authenticate(self.admin)

        data = {
            "receiver": {
                "type": ReceiverType.SYSLOG
            },
            "host": "bad",  # invalid host
            "port": 1,
            "protocol": SysLogSendProtocol.TCP
        }
        response = client.post(syslog_url, data=data, format='json')
        assert response.status_code == status.HTTP_400_BAD_REQUEST
        assert 'host' in response.data
        assert len(response.data) == 1  # only one error

    @pytest.mark.unit
    def test_patch_syslog_receiver_with_invalid_data(self):
        receiver = SyslogReceiver.objects.first()
        receiver_port = receiver.port

        syslog_url = reverse('export_syslog_receivers-detail', args=[receiver.id])

        client.force_authenticate(self.admin)

        data = {
            "port": "sad",  # invalid port
        }
        response = client.patch(syslog_url, data=data, format='json')
        assert response.status_code == status.HTTP_400_BAD_REQUEST
        assert 'port' in response.data
        assert len(response.data) == 1  # only one error

        receiver = SyslogReceiver.objects.first()
        assert receiver.port == receiver_port

    @pytest.mark.unit
    def test_delete_syslog_receiver(self):
        client.force_authenticate(self.admin)

        receiver = SyslogReceiver.objects.first()
        receiver_id = receiver.id

        syslog_url = reverse('export_syslog_receivers-detail', args=[receiver.id])

        client.delete(syslog_url)
        assert not SyslogReceiver.objects.filter(id=receiver_id).exists()

        response = client.get(syslog_url)
        assert response.status_code == status.HTTP_404_NOT_FOUND
