import base64

from django.contrib.auth import get_user_model
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers

from .models import *
from .services import *

class WireGuardVPNSerializer(serializers.ModelSerializer):
    class Meta:
        model = WireGuardVPN
        fields = [ 'wireguard_public_key' ]
        read_only_fields = [ 'address ' ]

        def create(self, validated_data):
            pass

# class WireGuardVPNPoolSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = WireGuardVPNPool
#         fields = '__all__'

# class WireGuardVPNSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = VPNNetworkReservation
#         fields = '__all__'


# class VPNNetworkSerializer(serializers.ModelSerializer):
#     class Meta:
#         model = VPNNetwork
#         fields = '__all__'

#     # This is required for finding the VPN pool, but does not
#     # exist in the model
#     network_size = serializers.IntegerField(min_value=0,
#                                             max_value=128,
#                                             write_only=True)

#     def validate_wireguard_public_key(self, value):
#         msg = _("Supplied key is not a valid wireguard public key")

#         """ FIXME: verify that this does not create broken wireguard config files,
#         i.e. contains \n or similar!
#         We might even need to be more strict to not break wireguard...
#         """

#         try:
#             base64.standard_b64decode(value)
#         except Exception as e:
#             raise serializers.ValidationError(msg)

#         if '\n' in value:
#             raise serializers.ValidationError(msg)

#         return value

#     def validate(self, data):

#         # FIXME: filter for status = active or similar
#         all_pools = VPNPool.objects.all()
#         sizes = [ p.subnetwork_size for p in all_pools ]

#         pools = VPNPool.objects.filter(subnetwork_size=data['network_size'])

#         if len(pools) == 0:
#             msg = _("No pool available for networks with size = {}. Available are: {}".format(data['network_size'], sizes))
#             raise serializers.ValidationError(msg)

#         return data

#     def create(self, validated_data):
#         """
#         Creating a new vpnnetwork - there are a couple of race conditions,
#         especially when run in parallel.

#         What we should be doing:

#         - create a reservation race free
#         - map the reservation to a network (?)
#         """

#         pools = VPNPool.objects.filter(subnetwork_size=validated_data['network_size'])

#         vpn_network = None

#         for pool in pools:
#             if pool.num_free_networks > 0:
#                 next_address = pool.next_free_network

#                 reservation, created = VPNNetworkReservation.objects.update_or_create(
#                     vpnpool=pool, address=next_address,
#                     defaults = {
#                         'status': 'used'
#                     })

#                 vpn_network = VPNNetwork.objects.create(
#                     owner=self.context['request'].user,
#                     network=reservation,
#                     wireguard_public_key=validated_data['wireguard_public_key']
#                 )

#                 break
#         if not vpn_network:
#             # FIXME: use correct exception
#             raise Exception("Did not find any free pool")


#         return vpn_network