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 = UserDeployments.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)
        
