from unittest.mock import patch

import pytest

from incident.models import Incident
from incident_export.enums import ReceiverType, SysLogSendProtocol
from incident_export.models import SyslogReceiver, OpcuaReceiver, Receiver
from incident_export.tasks import export_incident_syslog, export_incident_opcua


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

    @pytest.fixture(autouse=True)
    def testing_incident_export_api(self, django_user_model):
        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_syslog_incident_export_api(self):
        """ Test for checking if API executes correct amount of time for syslog receivers
            PASSED: if API executes correct amount of times, that equals enabled syslog receivers
            FAILED: Otherwise
        """
        with patch('logging.Logger.info') as mock_info:
            inc = Incident.objects.create(title='Incident',
                                          importance=10,
                                          event_count=10,
                                          events='')
            export_incident_syslog(inc)
            assert len(Receiver.objects.filter(export_status=True,
                                               type=ReceiverType.SYSLOG)) == mock_info.call_count

    @pytest.mark.unit
    def test_opcua_incident_export_api(self):
        """ Test for checking if API executes correct amount of time for OPCUA receivers
            PASSED: if API executes correct amount of times, that equals enabled OPCUA receivers
            FAILED: Otherwise
        """
        with patch('logging.Logger.info') as mock_info:
            inc = Incident.objects.create(title='Incident',
                                          importance=10,
                                          event_count=10,
                                          events='')
            export_incident_opcua(inc)
            assert len(Receiver.objects.filter(export_status=True,
                                               type=ReceiverType.OPCUA)) == mock_info.call_count

    @pytest.mark.unit
    def test_incident_export_api_after_disable(self):
        """ Test for checking if API doesnt trigger on disabled receivers
            PASSED: if API executes different amount of times before and after disabling receiver
            FAILED: otherwise
        """
        with patch('logging.Logger.info') as mock_info:
            inc = Incident.objects.create(title='Incident', importance=10, event_count=10, events='')
            export_incident_syslog(inc)
            # Get mock calls before any actions with receivers
            mocks_before = mock_info.call_count
            # Disabling receiver
            syslog_receiver = SyslogReceiver.objects.get(host='1.0.0.0').receiver
            syslog_receiver.export_status = False
            syslog_receiver.save()
            inc2 = Incident.objects.create(title='Incident', importance=10, event_count=10, events='')
            export_incident_syslog(inc2)
            # Get mock calls after second execution after disabling
            mocks_after = mock_info.call_count
            # Check if api executed different amount of times
            assert mocks_before != mocks_after - mocks_before
