import logging

from rest_framework import serializers

from assets.models.assets import OperatingSystem, AssetListGroup, Asset
from console.models import Connection
from networkmap.models import NetworkMap, NetworkMapBackgroundImage


class UserMapSerializer(serializers.ModelSerializer):
    class Meta:
        model = NetworkMap
        fields = ('__all__')


class UserMapNamesSerializer(serializers.ModelSerializer):
    class Meta:
        model = NetworkMap
        fields = ['name', 'id']


class NetworkMapBackgroundImagesSerializer(serializers.ModelSerializer):
    """ Serializer that are user to provide data for network map background images """
    description = serializers.SerializerMethodField()

    def get_description(self, obj):
        return obj.pk

    class Meta:
        model = NetworkMapBackgroundImage
        fields = ['id', 'name', 'description', 'network_map', 'bounds', 'locked', 'visible']


class NetmapOsSerializer(serializers.ModelSerializer):
    class Meta:
        model = OperatingSystem
        fields = ['name']


class NetmapGroupSerializer(serializers.ModelSerializer):
    id = serializers.SerializerMethodField()
    in_danger = serializers.IntegerField(default=0)

    def get_id(self, obj):
        return f'group{obj.id}'

    class Meta:
        model = AssetListGroup
        fields = '__all__'

    def to_representation(self, instance):
        return dict(data=super().to_representation(instance))


class NetmapElementsSerializer(serializers.ModelSerializer):
    id = serializers.SerializerMethodField()
    parent = serializers.SerializerMethodField()
    in_danger = serializers.SerializerMethodField()

    def get_in_danger(self, obj):
        if obj.incidents.count() > 0:
            return 1
        else:
            return 0

    def get_parent(self, obj):
        return f'group{obj.group.id}' if obj.group else None

    def get_id(self, obj):
        return f'element{obj.id}'

    class Meta:
        model = Asset
        fields = ['id', 'name', 'group', 'parent', 'in_danger', 'asset_type', 'incidents']

    def to_representation(self, instance):
        return dict(group='nodes', data=super().to_representation(instance))


class FinalSerializer(serializers.Serializer):
    elements = NetmapElementsSerializer(many=True)
    groups = NetmapGroupSerializer(many=True)


class AssetDangerSerializer(serializers.ModelSerializer):
    id = serializers.SerializerMethodField()

    def get_id(self, obj):
        return f'element{obj.id}'

    class Meta:
        model = Asset
        fields = ['id']


class AutoNetmapElementsSerializer(serializers.ModelSerializer):
    parent = serializers.SerializerMethodField()
    in_danger = serializers.SerializerMethodField()
    id = serializers.SerializerMethodField()
    ip = serializers.SerializerMethodField()

    def get_id(self, obj):
        return f'node{obj.id}'

    def get_ip(self, obj):
        if obj.name == obj.ip:
            return ''
        else:
            return obj.ip

    def get_in_danger(self, obj):
        if obj.incidents.count() > 0:
            return 1
        else:
            return 0

    def get_parent(self, obj):
        return f'group{obj.group.id}' if obj.group else None

    class Meta:
        model = Asset
        fields = ['id', 'name', 'group', 'parent', 'in_danger', 'asset_type', 'incidents', 'ip']

    def to_representation(self, instance):
        return dict(group='nodes', data=super().to_representation(instance))


class AutoNetmapConnectionsSerializer(serializers.ModelSerializer):
    source = serializers.SerializerMethodField()
    target = serializers.SerializerMethodField()
    id = serializers.SerializerMethodField()

    def get_id(self, obj):
        return f'edge{obj.id}'

    def get_source(self, obj):
        return f'node{obj.src_asset.id}'

    def get_target(self, obj):
        return f'node{obj.dst_asset.id}'

    class Meta:
        model = Connection
        fields = ['source', 'target', 'id']

    def to_representation(self, instance):
        return dict(group='edges', data=super().to_representation(instance))
