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 core.models.sliver import Sliver
from util.logger import Logger, logging
from observer.ansible import *

logger = Logger(level=logging.INFO)

class SyncControllerNetworks(OpenStackSyncStep):
    requested_interval = 0
    provides=[ControllerNetwork, Network]

    def alloc_subnet(self, uuid):
        a = 10
        b = uuid >> 32
        c = uuid & 0xffffffff
	d = 0

	cidr = '%d.%d.%d.%d/24'%(a,b,c,d)
	return cidr
	

    def fetch_pending(self, deleted):
        if (deleted):
            return ControllerNetwork.deleted_objects.all()
        else:
            return ControllerNetwork.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))


    def save_controller_network(self, controller_network):
            network_name = controller_network.network.name
            subnet_name = '%s-%d'%(network_name,controller_network.pk)
	    cidr = self.alloc_subnet(controller_network.pk)
	    slice = controller_network.network.slices.all()[0] # XXX: FIXME!!

	    network_fields = {'endpoint':controller_network.controller.auth_url,
			'admin_user':slice.creator.email, # XXX: FIXME
			'tenant_name':slice.name, # XXX: FIXME
			'admin_password':slice.creator.remote_password,
			'name':network_name,
			'subnet_name':subnet_name,
			'ansible_tag':'%s-%s@%s'%(network_name,slice.slicename,controller_network.controller.name),
			'cidr':cidr
			}

	    res = run_template('sync_controller_networks.yaml', network_fields, path = 'controller_networks')

	    if (len(res)!=2):
		raise Exception('Could not sync network %s'%controller_network.network.name)
	    else:
		network_id = res[0]['id'] 
		subnet_id = res[1]['id'] 
		controller_network.net_id = network_id
		controller_network.subnet = cidr
		controller_network.subnet_id = subnet_id
		controller_network.save()

            	logger.info("sync'ed subnet (%s) for network: %s" % (controller_network.subnet, controller_network.network))


    def sync_record(self, controller_network):
        logger.info("sync'ing network controller %s for network %s slice %s controller %s" % (controller_network, controller_network.network, str(controller_network.network.owner), controller_network.controller))

        if not controller_network.controller.admin_user:
            logger.info("controller %r has no admin_user, skipping" % controller_network.controller)
            return

        if controller_network.network.owner and controller_network.network.owner.creator:
            try:
                # update manager context
		# Bring back
                self.save_controller_network(controller_network)
                logger.info("saved network controller: %s" % (controller_network))
            except Exception,e:
                logger.log_exc("save network controller failed: %s" % controller_network)
                raise e


    def delete_record(self, controller_network):
        driver = OpenStackDriver().client_driver(caller=controller_network.network.owner.creator,
                                                 tenant=controller_network.network.owner.name,
                                                 controller=controller_network.controller.name)
        if (controller_network.router_id) and (controller_network.subnet_id):
            driver.delete_router_interface(controller_network.router_id, controller_network.subnet_id)
        if controller_network.subnet_id:
            driver.delete_subnet(controller_network.subnet_id)
        if controller_network.router_id:
            driver.delete_router(controller_network.router_id)
        if controller_network.net_id:
            driver.delete_network(controller_network.net_id)
