from django.utils.translation import gettext_lazy
from rest_framework import serializers

from ncircc.enums.notifications import EventTypeEnum
from ncircc.models.notification import Notification, NotificationCategoryEnum

type_for_incident = {EventTypeEnum.INVOLVING_INTO_MALWARE_INFRASTRUCTURE.value,
                     EventTypeEnum.SLOWDOWN_DUE_TO_DDOS.value, EventTypeEnum.INFECT_MALWARE.value,
                     EventTypeEnum.CAPTURE_NETWORK_TRAFFIC.value, EventTypeEnum.USING_FOR_PHISHING.value,
                     EventTypeEnum.COMPROMISE_ACCOUNT.value, EventTypeEnum.UNAUTHORIZED_CHANGE_INFORMATION.value,
                     EventTypeEnum.UNAUTHORIZED_DISCLOSURE_INFORMATION.value,
                     EventTypeEnum.PUBLICATION_PROHIBITED_INFORMATION_RU.value,
                     EventTypeEnum.SENDING_SPAM_FROM_RESOURCE.value, EventTypeEnum.SUCCESSFUL_EXPLOITED_MALWARE.value}
type_for_attack = {EventTypeEnum.DDOS.value, EventTypeEnum.AUTHORIZATION_ERROR.value,
                   EventTypeEnum.ATTEMPT_INJECT_MALWARE.value, EventTypeEnum.ATTEMPT_EXPLOITED_MALWARE.value,
                   EventTypeEnum.FRAUDULENT_INFORMATION.value, EventTypeEnum.NETWORK_SCANNING.value,
                   EventTypeEnum.SOCIAL_ENGINEERING.value}
type_for_vulnerability = {EventTypeEnum.VULNERABLE_RESOURCE.value}

category_required_types_map = {NotificationCategoryEnum.INCIDENT.value: type_for_incident,
                               NotificationCategoryEnum.ATTACK.value: type_for_attack,
                               NotificationCategoryEnum.VULNERABILITY: type_for_vulnerability}


class NotificationSerializer(serializers.ModelSerializer):
    """Serializer for Notification NCIRCC."""

    comments_count = serializers.SerializerMethodField(read_only=True)

    def get_comments_count(self, notification: Notification) -> int:
        try:
            count = notification.new_comment_count
        except AttributeError:
            count = 0
        return count

    class Meta:
        model = Notification
        fields = ('id', 'incident', 'update_time', 'uuid', 'identifier', 'category', 'type', 'activity_status', 'tlp',
                  'affected_system_name', 'affected_system_category', 'event_description',
                  'affected_system_connection', 'assistance', 'notification_status', 'vulnerability_id',
                  'product_category', 'integrity_impact', 'availability_impact', 'confidentiality_impact',
                  'custom_impact', 'created', 'updated', 'comments_count', 'sending_time')
        read_only_fields = ('update_time', 'uuid', 'identifier', 'sending_time')
        extra_kwargs = {
            'incident': {'required': True, 'allow_null': False}
        }

    def validate(self, data: dict) -> dict:
        event_type = data.get('type')
        category = data.get('category')

        types_req = category_required_types_map.get(category)
        if types_req is None or event_type not in types_req:
            err = {'type': gettext_lazy(f'Incorrect type "{event_type}" for category "{category}"')}
            raise serializers.ValidationError(err)
        return data
