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.site import Deployment, SiteDeployment
from core.models.slice import Slice, SliceDeployment
from core.models.userdeployments import UserDeployment
from util.logger import Logger, logging
from observer.ansible import *

logger = Logger(level=logging.INFO)

class SyncSliceDeployment(OpenStackSyncStep):
    provides=[SliceDeployment]
    requested_interval=0

    def fetch_pending(self, deleted):
        if (deleted):
            return SliceDeployment.deleted_objects.all()
        else:
            return SliceDeployment.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 sync_record(self, slice_deployment):
        logger.info("sync'ing slice deployment %s" % slice_deployment)

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

	deployment_users = UserDeployment.objects.filter(user=slice_deployment.slice.creator,
                                                             deployment=slice_deployment.deployment)            
    	if not deployment_users:
	    logger.info("slice createor %s has not accout at deployment %s" % (slice_deployment.slice.creator, slice_deployment.deployment.name))
	    roles = []
    	else:
	    deployment_user = deployment_users[0]
	    roles = ['admin']
	    
	max_instances=int(slice_deployment.slice.max_slivers)
	tenant_fields = {'endpoint':slice_deployment.deployment.auth_url,
		         'admin_user': slice_deployment.deployment.admin_user,
		         'admin_password': slice_deployment.deployment.admin_password,
		         'admin_tenant': 'admin',
		         'tenant': slice_deployment.slice.name,
		         'tenant_description': slice_deployment.slice.description,
			 'roles':roles,
			 'name':deployment_user.email,
			 'max_instances':max_instances}

	res = run_template('sync_slice_deployments.yaml', tenant_fields)
	expected_num = len(roles)+1
	if (len(res)!=expected_num):
	    raise Exception('Could not sync tenants for slice %s'%slice_deployment.slice.name)
	else:
	    tenant_id = res[0]['id']
	    if (not slice_deployment.tenant_id):
	        handle = os.popen('nova quota-update --instances %d %s'%(max_instances,tenant_id))
		output = handle.read()
		result = handle.close()
		if (result):
		    logging.info('Could not update quota for %s'%slice_deployment.slice.name)
		slice_deployment.tenant_id = tenant_id
		slice_deployment.save()
			


    def delete_record(self, slice_deployment):
        user = User.objects.get(id=slice_deployment.slice.creator.id)
        driver = OpenStackDriver().admin_driver(deployment=slice_deployment.deployment.name)
        client_driver = driver.client_driver(caller=user,
                                             tenant=slice_deployment.slice.name,
                                             deployment=slice_deployment.deployment.name)

        if slice_deployment.router_id and slice_deployment.subnet_id:
            client_driver.delete_router_interface(slice_deployment.router_id, slice_deployment.subnet_id)
        if slice_deployment.subnet_id:
            client_driver.delete_subnet(slice_deployment.subnet_id)
        if slice_deployment.router_id:    
            client_driver.delete_router(slice_deployment.router_id)
        if slice_deployment.network_id:
            client_driver.delete_network(slice_deployment.network_id)
        if slice_deployment.tenant_id:
            driver.delete_tenant(slice_deployment.tenant_id)
        
