import logging
from ipaddress import IPv4Network
from rest_framework import serializers

logger = logging.getLogger(__name__)

class CIDRValidator(object):
    def __init__(self, value, brothers=None, parent=None):
        logger.debug("creating %s with %s %s %s" % (self.__class__, value, brothers, parent))
        try:
            self.value = IPv4Network(value)
            if parent == None:
                self.parent = None
            else:
                self.parent = IPv4Network(parent)
            if brothers == None:
                self.brothers = None
            else:
                self.brothers = list()
                for b in brothers:
                    self.brothers.append(IPv4Network(b))
        except ValueError as e:
            raise serializers.ValidationError(e)

    def validate_parent(self):
        if self.parent == None:
            logger.debug('(%s) has no parent' % self.value)
            return True

        # if the mask is bigger
        logger.debug('comparing prefixlen of %s and %s' %
            (self.value, self.parent))
        if self.value.prefixlen < self.parent.prefixlen:
            raise serializers.ValidationError(
                    '%s is bigger than %s' %
                    (self.value, self.parent))

        # is the network overlapping with self
        logger.debug('testing disjonction of %s and %s' %
            (self.value, self.parent))
        if not self.value.overlaps(self.parent):
            raise serializers.ValidationError(
                    '%s and %s are disjoints' %
                    (self.parent, self.value))

        return True

    def validate_brothers(self):
        if self.brothers == None:
            logger.debug('(%s) has no brothers' % self.value)
            return True

        # checks if it's already registered
        for bro in self.brothers:
            logger.debug('testing equality of %s and %s' %
                (self.value, bro))
            if (bro == self.value):
                raise serializers.ValidationError(
                        '%s is already allocated' % self.value)
            logger.debug('testing overlapping of %s and %s' %
                (self.value, bro))
            if (bro.overlaps(self.value)):
                raise serializers.ValidationError(
                        '%s and %s overlaps' %
                        (bro, self.value))

        return True

    def validate(self):
        return(self.validate_parent() and
                self.validate_brothers())

    def normalize_value(self):
        return self.value.with_prefixlen

class IPValidator(CIDRValidator):
    def __init__(self, value, brothers=None, parent=None):
        super().__init__(value, brothers, parent)

        if (self.value.prefixlen != 32):
            raise serializers.ValidationError('%s is not a /32 cidr' % self.value)

    def normalize_value(self):
        return self.value.network_address

if __name__ == "__main__":
    print(CIDRValidator(value="10.11.0.0/16", parent="10.0.0.0/24",
        brothers=iter(("10.10.0.0/16", "10.10.0.0/15"))).validate())
