import pytest

from incident.models import Incident
from ncircc.enums.notifications import NotificationCategoryEnum, EventTypeEnum
from ncircc.serializers.notification import NotificationSerializer


@pytest.mark.django_db
class TestNotificationSerializer:

    @pytest.fixture(autouse=True)
    def setup_test(self):
        self.incident = Incident.objects.create(title='test_inc', importance=10, event_count=10, events='')

    @pytest.mark.unit
    @pytest.mark.parametrize('category, event_type', (
        # Vulnerability
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.VULNERABLE_RESOURCE.value),
        # Incident
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.INVOLVING_INTO_MALWARE_INFRASTRUCTURE.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.SLOWDOWN_DUE_TO_DDOS.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.INFECT_MALWARE.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.CAPTURE_NETWORK_TRAFFIC.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.USING_FOR_PHISHING.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.COMPROMISE_ACCOUNT.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.UNAUTHORIZED_CHANGE_INFORMATION.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.UNAUTHORIZED_DISCLOSURE_INFORMATION.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.PUBLICATION_PROHIBITED_INFORMATION_RU.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.SENDING_SPAM_FROM_RESOURCE.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.SUCCESSFUL_EXPLOITED_MALWARE.value),
        # Attack
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.DDOS.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.AUTHORIZATION_ERROR.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.ATTEMPT_INJECT_MALWARE.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.ATTEMPT_EXPLOITED_MALWARE.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.FRAUDULENT_INFORMATION.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.NETWORK_SCANNING.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.SOCIAL_ENGINEERING.value),
    ))
    def test_validate_event_type_and_category_valid(self, category: str, event_type: str):
        data = {
            'incident': self.incident.pk,
            'category': category,
            'type': event_type,
            'event_description': 'description',
            'affected_system_name': 'name'
        }
        serializer = NotificationSerializer(data=data)
        assert serializer.is_valid()

    @pytest.mark.unit
    @pytest.mark.parametrize('category, event_type', (
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.DDOS.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.AUTHORIZATION_ERROR.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.ATTEMPT_INJECT_MALWARE.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.ATTEMPT_EXPLOITED_MALWARE.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.FRAUDULENT_INFORMATION.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.NETWORK_SCANNING.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.SOCIAL_ENGINEERING.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.INVOLVING_INTO_MALWARE_INFRASTRUCTURE.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.SLOWDOWN_DUE_TO_DDOS.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.INFECT_MALWARE.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.CAPTURE_NETWORK_TRAFFIC.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.USING_FOR_PHISHING.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.COMPROMISE_ACCOUNT.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.UNAUTHORIZED_CHANGE_INFORMATION.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.UNAUTHORIZED_DISCLOSURE_INFORMATION.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.PUBLICATION_PROHIBITED_INFORMATION_RU.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.SENDING_SPAM_FROM_RESOURCE.value),
        (NotificationCategoryEnum.VULNERABILITY.value, EventTypeEnum.SUCCESSFUL_EXPLOITED_MALWARE.value),

        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.VULNERABLE_RESOURCE.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.DDOS.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.AUTHORIZATION_ERROR.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.ATTEMPT_INJECT_MALWARE.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.ATTEMPT_EXPLOITED_MALWARE.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.FRAUDULENT_INFORMATION.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.NETWORK_SCANNING.value),
        (NotificationCategoryEnum.INCIDENT.value, EventTypeEnum.SOCIAL_ENGINEERING.value),

        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.VULNERABLE_RESOURCE.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.INVOLVING_INTO_MALWARE_INFRASTRUCTURE.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.SLOWDOWN_DUE_TO_DDOS.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.INFECT_MALWARE.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.CAPTURE_NETWORK_TRAFFIC.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.USING_FOR_PHISHING.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.COMPROMISE_ACCOUNT.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.UNAUTHORIZED_CHANGE_INFORMATION.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.UNAUTHORIZED_DISCLOSURE_INFORMATION.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.PUBLICATION_PROHIBITED_INFORMATION_RU.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.SENDING_SPAM_FROM_RESOURCE.value),
        (NotificationCategoryEnum.ATTACK.value, EventTypeEnum.SUCCESSFUL_EXPLOITED_MALWARE.value),

    ))
    def test_validate_event_type_and_category_not_valid(self, category: str, event_type: str):
        """Testing chose select data."""
        data = {
            'incident': self.incident.pk,
            'category': category,
            'type': event_type,
            'event_description': 'description',
            'affected_system_name': 'name'
        }
        serializer = NotificationSerializer(data=data)
        assert not serializer.is_valid()
        assert 'type' in serializer.errors
