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=[Network, ControllerNetwork, Sliver]

    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)
