# encoding: utf-8
# -*- coding: utf-8 -*-
# author = ‘LW’
import logging
from rest_framework import serializers
from .models import Server, Cloud, Ip
import pytz

logger = logging.getLogger(__name__)
tz = pytz.timezone('Asia/Shanghai')


class ServerSerializer(serializers.Serializer):
    id = serializers.ReadOnlyField()
    cloud = serializers.PrimaryKeyRelatedField(queryset=Cloud.objects.all(), many=False)
    instanceId = serializers.CharField(required=True)
    instanceType = serializers.CharField(required=True)
    cpu = serializers.CharField(required=True)
    memory = serializers.CharField(required=True)
    instanceName = serializers.CharField(required=True),
    creationTime = serializers.DateTimeField(required=True, format='%Y-%m-%d %H:%M:%S', default_timezone=tz)
    startTime = serializers.DateTimeField(required=True, format='%Y-%m-%d %H:%M:%S', default_timezone=tz)
    expiredTime = serializers.DateTimeField(required=True, format='%Y-%m-%d %H:%M:%S', default_timezone=tz)
    hostName = serializers.CharField(required=True)
    publicIps = serializers.ListField(required=True, write_only=True)
    innerIps = serializers.ListField(required=True, write_only=True)

    class Meta:
        model = Server
        fields = "__all__"

    def getCloudPk(self, code):
        try:
            obj = Cloud.objects.get(code__exact=code)
            return obj.id
        except Cloud.DoesNotExist:
            logger.error("云厂商不存在: {}".format(code))
            raise serializers.ValidationError("云厂商不存在")
        except Exception as e:
            logger.error("云厂商错误: {}".format(e.args))
            raise serializers.ValidationError("云厂商错误")

    def to_internal_value(self, data):
        data["cloud"] = self.getCloudPk(data["cloud"])
        # print("to_internal_value: ", data)
        return super(ServerSerializer, self).to_internal_value(data)

    def getInstance(self, instanceId):
        try:
            return Server.objects.get(instanceId__exact=instanceId)
        except Server.DoesNotExist:
            return None
        except Exception as e:
            logger.error("服务器错误: ".format(e.args))
            raise serializers.ValidationError("服务器错误")

    def create(self, validated_data):
        instance = self.getInstance(validated_data["instanceId"])
        if instance is not None:
            return self.update(instance, validated_data)
        innerIps = validated_data.pop("innerIps")
        publicIps = validated_data.pop("publicIps")
        instance = Server.objects.create(**validated_data)
        self.check_inner_ip(instance, innerIps)
        self.check_public_ip(instance, publicIps)
        return instance

    def update(self, instance, validated_data):
        # TO-DO 未实现服务器修改

        instance.creationTime = validated_data.get("creationTime", "").astimezone(tz)
        instance.startTime = validated_data.get("startTime", "").astimezone(tz)
        instance.expiredTime = validated_data.get("expiredTime", "").astimezone(tz)
        # print(instance.creationTime, instance.startTime, instance.expiredTime)
        instance.save()
        self.check_inner_ip(instance, validated_data['innerIps'])
        self.check_public_ip(instance, validated_data['publicIps'])
        return instance

    def check_inner_ip(self, instance, innerIps):
        ip_queryset = instance.innerIpAddress.all()
        current_ip_objs = []
        for ip in innerIps:
            try:
                ip_obj = ip_queryset.get(ip__exact=ip)
            except Ip.DoesNotExist:
                ip_obj = Ip.objects.create(ip=ip, inner=instance)
            current_ip_objs.append(ip_obj)
        self.cleanip(ip_queryset, current_ip_objs)

    def check_public_ip(self, instance, publicIps):
        ip_queryset = instance.publicIpAddress.all()
        current_ip_objs = []
        for ip in publicIps:
            try:
                ip_obj = ip_queryset.get(ip__exact=ip)
            except Ip.DoesNotExist:
                ip_obj = Ip.objects.create(ip=ip, public=instance)
            current_ip_objs.append(ip_obj)
        self.cleanip(ip_queryset, current_ip_objs)

    def cleanip(self, ip_queryset, current_ip_objs):
        not_exists_ip = set(ip_queryset) - set(current_ip_objs)
        for obj in not_exists_ip:
            obj.delete()

    def to_representation(self, instance):

        ret = super(ServerSerializer, self).to_representation(instance)
        ret['cloud'] = {
            'code': instance.cloud.code,
            'name': instance.cloud.name,
        }

        ret['innerIps'] = [ip.ip for ip in instance.innerIpAddress.all()]
        ret['publicIps'] = [ip.ip for ip in instance.publicIpAddress.all()]
        return ret
