import logging

from rest_framework import serializers

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

_log = logging.getLogger(__name__)


class CreateUpdateEventReceiverMixin:
    receiver_map = {
        SyslogReceiver: ReceiverType.SYSLOG,
        OpcuaReceiver: ReceiverType.OPCUA
    }

    def create(self, validated_data):
        """
            Before creating the receiver (SyslogReceiver or OpcuaReceiver) we create an EventReceiver -
                object with the receiver type and basic settings.
            This object will be connected to the receiver via OneToOneField.
            We also check that the types of the receiver and EventReceiver match
        """

        receiver_data = validated_data['receiver']
        receiver_data['type'] = self.receiver_map[self.Meta.model]
        receiver = Receiver.objects.create(**receiver_data)
        validated_data['receiver'] = receiver
        return super().create(validated_data)

    def update(self, instance, validated_data):
        receiver_data = validated_data.pop('receiver', None)
        if receiver_data:
            # update EventReceiver if passed data in request only
            receiver_data['type'] = self.receiver_map[self.Meta.model]
            receiver = instance.receiver
            receiver_serializer = self.fields['receiver']
            receiver_serializer.update(receiver, receiver_data)
        return super().update(instance, validated_data)


class ReceiverSerializer(serializers.ModelSerializer):
    class Meta:
        model = Receiver
        fields = '__all__'


class SyslogReceiverSerializer(CreateUpdateEventReceiverMixin, serializers.ModelSerializer):
    receiver = ReceiverSerializer()

    class Meta:
        model = SyslogReceiver
        fields = '__all__'


class OpcuaReceiverSerializer(CreateUpdateEventReceiverMixin, serializers.ModelSerializer):
    receiver = ReceiverSerializer()

    class Meta:
        model = OpcuaReceiver
        fields = '__all__'


class ChangeStateReceiverSerializer(serializers.Serializer):
    ids = serializers.ListField(child=serializers.IntegerField())
    status = serializers.BooleanField()
