
# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import ipaddress
import random
from synchronizers.new_base.modelaccessor import NodeToSwitchPort, PortInterface, model_accessor
from synchronizers.new_base.policy import Policy

from xosconfig import Config
from multistructlog import create_logger

from helpers import Helpers

log = create_logger(Config().get('logging'))

class ComputeNodePolicy(Policy):
    model_name = "NodeToSwitchPort"

    @staticmethod
    def getLastAddress(network):
        return str(network.network_address + network.num_addresses - 2) + "/" + str(network.prefixlen)
        # return ipaddress.ip_interface(network.network_address + network.num_addresses - 2)

    @staticmethod
    def getPortCidrByIp(ip):
        interface = ipaddress.ip_interface(ip)
        network = ipaddress.ip_network(interface.network)
        cidr = ComputeNodePolicy.getLastAddress(network)
        return cidr

    @staticmethod
    def generateVlan(used_vlans):
        availabel_tags = range(16, 4093)
        valid_tags = list(set(availabel_tags) - set(used_vlans))
        if len(valid_tags) == 0:
            raise Exception("No VLANs left")
        return random.choice(valid_tags)

    @staticmethod
    def getVlanByCidr(subnet):
        # vlanUntagged is unique per subnet
        same_subnet_ifaces = PortInterface.objects.filter(ips=str(subnet))

        if len(same_subnet_ifaces) > 0:
            return same_subnet_ifaces[0].vlanUntagged
        else:
            PortInterface.objects.all()
            used_vlans = list(set([i.vlanUntagged for i in same_subnet_ifaces]))
            log.info("MODEL_POLICY: used vlans", vlans=used_vlans, subnet=subnet)
            return ComputeNodePolicy.generateVlan(used_vlans)

    def handle_create(self, node_to_port):
        return self.handle_update(node_to_port)

    def handle_update(self, node_to_port):
        log.info("MODEL_POLICY: NodeToSwitchPort %s handle update" % node_to_port.id, node=node_to_port.node, port=node_to_port.port, switch=node_to_port.port.switch)

        compute_node = node_to_port.node

        cidr = ComputeNodePolicy.getPortCidrByIp(compute_node.dataPlaneIp)

        # check if an interface already exists
        try:
            PortInterface.objects.get(
                port_id=node_to_port.port.id,
                name=compute_node.dataPlaneIntf,
                ips=str(cidr)
            )
        except IndexError:

            vlan = self.getVlanByCidr(cidr)

            log.info("MODEL_POLICY: choosen vlan", vlan=vlan, cidr=cidr)

            interface = PortInterface(
                port_id=node_to_port.port.id,
                name=compute_node.dataPlaneIntf,
                ips=str(cidr),
                vlanUntagged=vlan
            )

            interface.save()
        
        # TODO if the model is updated I need to remove the old interface, how?


    def handle_delete(self, node_to_port):
        pass
