import os
import base64
from collections import defaultdict
from netaddr import IPAddress, IPNetwork
from django.db.models import F, Q
from planetstack.config import Config
from observer.openstacksyncstep import OpenStackSyncStep
from core.models.network import *
from core.models.slice import *
from util.logger import Logger, logging

logger = Logger(level=logging.INFO)

class SyncNetworkDeployments(OpenStackSyncStep):
    provides=[NetworkDeployments]
    request_interval = 0 
    
    def fetch_pending(self):
        # network deployments are not visible to users. We must ensure
        # networks are deployed at all deploymets available to their slices. 
        slice_deployments = SliceDeployments.objects.all()
        slice_deploy_lookup = defaultdict(list)
        for slice_deployment in slice_deployments:
            slice_deploy_lookup[slice_deployment.slice].append(slice_deployment.deployment)
        
        network_deployments = NetworkDeployments.objects.all()
        network_deploy_lookup = defaultdict(list)
        for network_deployment in network_deployments:
            network_deploy_lookup[network_deployment.network].append(network_deployment.deployment)

        for network in Network.objects.filter():
            expected_deployments = slice_deploy_lookup[network.owner]
            for expected_deployment in expected_deployments:
                if network not in network_deploy_lookup or \
                  expected_deployment not in network_deploy_lookup[network]:
                    nd = NetworkDeployments(network=network, deployment=expected_deployment)
                    nd.save()
        return NetworkDeployments.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))

    def get_next_subnet(self, deployment=None):
        # limit ourself to 10.0.x.x for now
        valid_subnet = lambda net: net.startswith('10.0')
        driver = self.driver.admin_driver(deployment=deployment)
        subnets = driver.shell.quantum.list_subnets()['subnets']
        ints = [int(IPNetwork(subnet['cidr']).ip) for subnet in subnets \
                if valid_subnet(subnet['cidr'])]
        ints.sort()
        if ints:
            last_ip = IPAddress(ints[-1])
        else:
            last_ip = IPAddress('10.0.0.1')
        last_ip = IPAddress(ints[-1])
        last_network = IPNetwork(str(last_ip) + "/24")
        next_network = IPNetwork(str(IPAddress(last_network) + last_network.size) + "/24")
        return next_network

    def save_network_deployment(self, network_deployment):
        if not network_deployment.network_id and network_deployment.network.template.sharedNetworkName:
            network_deployment.network_id = network_deployment.network.template.sharedNetworkId

        if not network_deployment.net_id:
            network_name = network_deployment.network.name

            # create network
            os_network = self.driver.create_network(network_name, shared=True)
            network_deployment.net_id = os_network['id']

            # create router
            router = self.driver.create_router(network_name)
            network_deployment.router_id = router['id']

            # create subnet
            next_subnet = self.get_next_subnet(deployment=network_deployment.deployment.name)
            cidr = str(next_subnet.cidr)
            ip_version = next_subnet.version
            start = str(next_subnet[2])
            end = str(next_subnet[-2])
            subnet = self.driver.create_subnet(name=network_name,
                                               network_id = network_deployment.net_id,
                                               cidr_ip = cidr,
                                               ip_version = ip_version,
                                               start = start,
                                               end = end)
            network_deployment.subnet = cidr
            network_deployment.subnet_id = subnet['id']
            # add subnet as interface to slice's router
            self.driver.add_router_interface(router['id'], subnet['id'])
            # add external route
            self.driver.add_external_route(subnet)
            logger.info("created private subnet (%s) for network: %s" % (cidr, network_deployment.network))
        else:
            (network_deployment.subnet_id, network_deployment.subnet) = self.driver.get_network_subnet(network_deployment.net_id)
            logger.info("sync'ed subnet (%s) for network: %s" % (network_deployment.subnet, network_deployment.network))

        network_deployment.save()

    def sync_record(self, network_deployment):
        if network_deployment.network.owner and network_deployment.network.owner.creator:
            try:
                # update manager context
                real_driver = self.driver
                self.driver = self.driver.client_driver(caller=network_deployment.network.owner.creator, 
                                                        tenant=network_deployment.network.owner.name,
                                                        deployment=network_deployment.deployment.name)
                self.save_network_deployment(network_deployment)
                self.driver = real_driver
                logger.info("saved network deployment: %s" % (network_deployment))
            except Exception,e:
                logger.log_exc("save network deployment failed: %s" % network_deployment)
                raise e            
        
          
    
