import os
import base64
from django.db.models import F, Q
from planetstack.config import Config
from observer.openstacksyncstep import OpenStackSyncStep
from core.models.sliver import Sliver
from core.models.slice import Slice, SlicePrivilege, ControllerSlices
from core.models.network import Network, NetworkSlice, ControllerNetworks
from util.logger import Logger, logging
from observer.ansible import *

logger = Logger(level=logging.INFO)

def escape(s):
    s = s.replace('\n',r'\n').replace('"',r'\"')
    return s

class SyncSlivers(OpenStackSyncStep):
    provides=[Sliver]
    requested_interval=0

    def get_userdata(self, sliver):
        userdata = 'opencloud:\n   slicename: "%s"\n   hostname: "%s"\n' % (sliver.slice.name, sliver.node.name)
        return userdata

    def sync_record(self, sliver):
        logger.info("sync'ing sliver:%s slice:%s controller:%s " % (sliver, sliver.slice.name, sliver.node.site_deployment.controller))

        metadata_update = {}
        if (sliver.numberCores):
            metadata_update["cpu_cores"] = str(sliver.numberCores)

        for tag in sliver.slice.tags.all():
            if tag.name.startswith("sysctl-"):
                metadata_update[tag.name] = tag.value

        # public keys
        slice_memberships = SlicePrivilege.objects.filter(slice=sliver.slice)
        pubkeys = set([sm.user.public_key for sm in slice_memberships if sm.user.public_key])
        if sliver.creator.public_key:
            pubkeys.add(sliver.creator.public_key)

        if sliver.slice.creator.public_key:
            pubkeys.add(sliver.slice.creator.public_key)

        nics = []
        networks = [ns.network for ns in NetworkSlice.objects.filter(slice=sliver.slice)]
        controller_networks = ControllerNetworks.objects.filter(network__in=networks,
                                                                controller=sliver.node.site_deployment.controller)

        for controller_network in controller_networks:
            if controller_network.network.template.visibility == 'private' and \
               controller_network.network.template.translation == 'none' and controller_network.net_id:
                nics.append(controller_network.net_id)

        # now include network template
        network_templates = [network.template.shared_network_name for network in networks \
                             if network.template.shared_network_name]

        #driver = self.driver.client_driver(caller=sliver.creator, tenant=sliver.slice.name, controller=sliver.controllerNetwork)
        driver = self.driver.admin_driver(tenant='admin', controller=sliver.controllerNetwork)
        nets = driver.shell.quantum.list_networks()['networks']
        for net in nets:
            if net['name'] in network_templates:
                nics.append(net['id'])

        if (not nics):
            for net in nets:
                if net['name']=='public':
                    nics.append(net['id'])

        # look up image id
        controller_driver = self.driver.admin_driver(controller=sliver.controllerNetwork)
        image_id = None
        images = controller_driver.shell.glanceclient.images.list()
        for image in images:
            if image.name == sliver.image.name or not image_id:
                image_id = image.id

        # look up key name at the controller
        # create/fetch keypair
        keyname = None
        keyname = sliver.creator.email.lower().replace('@', 'AT').replace('.', '') +\
                  sliver.slice.name
        key_fields =  {'name': keyname,
                       'public_key': sliver.creator.public_key}

        try:
            legacy = Config().observer_legacy
        except:
            legacy = False

        if (legacy):
            host_filter = sliver.node.name.split('.',1)[0]
        else:
            host_filter = sliver.node.name

        availability_zone_filter = 'nova:%s'%host_filter
        sliver_name = '%s-%d'%(sliver.slice.name,sliver.id)

        userData = self.get_userdata(sliver)
        if sliver.userData:
            userData = sliver.userData

        controller = sliver.controllerNetwork
        tenant_fields = {'endpoint':controller.auth_url,
                     'admin_user': sliver.creator.username,
                     'admin_password': sliver.creator.password,
                     'admin_tenant': sliver.slice.name,
                     'tenant': sliver.slice.name,
                     'tenant_description': sliver.slice.description,
                     'name':sliver_name,
                     'ansible_tag':sliver_name,
                     'availability_zone': availability_zone_filter,
                     'image_id':image_id,
                     'key_name':keyname,
                     'flavor_id':3,
                     'nics':nics,
                     'meta':metadata_update,
                     'key':key_fields,
                     'user_data':r'%s'%escape(userData)}

        res = run_template('sync_slivers.yaml', tenant_fields,path='slivers')
        if (len(res)!=2):
            raise Exception('Could not sync sliver %s'%sliver.slice.name)
        else:
            sliver_id = res[1]['id'] # 0 is for the key

            sliver.instance_id = sliver_id
            sliver.instance_name = sliver_name
            sliver.save()

    def delete_record(self, sliver):
        sliver_name = '@'.join([sliver.slice.name,sliver.node.name])
        tenant_fields = {'name':sliver_name,
                         'ansible_tag':sliver_name
                        }
        res = run_template('delete_slivers.yaml', tenant_fields, path='slivers')
