import os
import base64
import socket
from xos.config import Config
from synchronizers.openstack.openstacksyncstep import OpenStackSyncStep
from synchronizers.new_base.ansible_helper import *
from synchronizers.new_base.syncstep import *
from xos.logger import observer_logger as logger
from synchronizers.new_base.modelaccessor import *

RESTAPI_HOSTNAME = getattr(Config(), "server_restapi_hostname", getattr(Config(), "server_hostname", socket.gethostname()))
RESTAPI_PORT = int(getattr(Config(), "server_restapi_port", getattr(Config(), "server_port", "8000")))

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

class SyncInstances(OpenStackSyncStep):
    provides=[Instance]
    requested_interval=0
    observes=Instance
    playbook='sync_instances.yaml'

    def fetch_pending(self, deletion=False):
        objs = super(SyncInstances, self).fetch_pending(deletion)
        objs = [x for x in objs if x.isolation=="vm"]
        return objs

    def get_userdata(self, instance, pubkeys):
        userdata = '#cloud-config\n\nopencloud:\n   slicename: "%s"\n   hostname: "%s"\n   restapi_hostname: "%s"\n   restapi_port: "%s"\n' % (instance.slice.name, instance.node.name, RESTAPI_HOSTNAME, str(RESTAPI_PORT))
        userdata += 'ssh_authorized_keys:\n'
        for key in pubkeys:
            userdata += '  - %s\n' % key
        return userdata

    def get_nic_for_first_slot(self, nics):
        # Try to find a NIC with "public" visibility
        for nic in nics[:]:
            network=nic.get("network", None)
            if network:
                tem = network.template
                if (tem.visibility == "public"):
                    return nic

        # Otherwise try to find a private network
        for nic in nics[:]:
            network=nic.get("network", None)
            if network:
                tem = network.template
                if (tem.visibility == "private") and (tem.translation=="none") and ("management" not in tem.name):
                   return nic

        raise Exception("Could not find a NIC for first slot")

    def sort_nics(self, nics):
        result = []

        # Enforce VTN's network order requirement for vSG.  The access network must be
        # inserted into the first slot. The management network must be inserted
        # into the second slot.
        #
        # Some VMs may connect to multiple networks that advertise gateways.  In this case, the
        # default gateway is enforced on eth0.  So give priority to "public" networks when 
        # choosing a network for the first slot.

        nic = self.get_nic_for_first_slot(nics)
        result.append(nic)
        nics.remove(nic)

        # move the management network to the second spot
        for nic in nics[:]:
            network=nic.get("network", None)
            if network:
                tem = network.template
                if (tem.visibility == "private") and (tem.translation=="none") and ("management" in tem.name):
#MCORD
#                    if len(result)!=1:
#                        raise Exception("Management network needs to be inserted in slot 1, but there are %d private nics" % len(result))
                    result.append(nic)
                    nics.remove(nic)

        # add everything else. For VTN there probably shouldn't be any more.
        result.extend(nics)

        return result

    def map_sync_inputs(self, instance):

        # sanity check - make sure model_policy for slice has run
        if ((not instance.slice.policed) or (instance.slice.policed < instance.slice.updated)):
            raise DeferredException("Instance %s waiting on Slice %s to execute model policies" % (instance, slice.name))

        # sanity check - make sure model_policy for all slice networks have run
        for network in instance.slice.ownedNetworks.all():
            if ((not network.policed) or (network.policed < network.updated)):
                raise DeferredException("Instance %s waiting on Network %s to execute model policies" % (instance, network.name))

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

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

	slice_memberships = SlicePrivilege.objects.filter(slice_id=instance.slice.id)
        pubkeys = set([sm.user.public_key for sm in slice_memberships if sm.user.public_key])
        if instance.creator.public_key:
            pubkeys.add(instance.creator.public_key)

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

        if instance.slice.service and instance.slice.service.public_key:
            pubkeys.add(instance.slice.service.public_key)

        nics=[]

        # handle ports the were created by the user
        port_ids=[]
        for port in Port.objects.filter(instance_id=instance.id):
            if not port.port_id:
                raise DeferredException("Instance %s waiting on port %s" % (instance, port))
            nics.append({"kind": "port", "value": port.port_id, "network": port.network})

        # we want to exclude from 'nics' any network that already has a Port
        existing_port_networks = [port.network for port in Port.objects.filter(instance_id=instance.id)]
        existing_port_network_ids = [x.id for x in existing_port_networks]

        networks = [ns.network for ns in NetworkSlice.objects.filter(slice_id=instance.slice.id) if ns.network.id not in existing_port_network_ids]
        networks_ids = [x.id for x in networks]
        controller_networks = ControllerNetwork.objects.filter(controller_id=instance.node.site_deployment.controller.id)
        controller_networks = [x for x in controller_networks if x.id in networks_ids]


        for network in networks:
           if not ControllerNetwork.objects.filter(network_id=network.id, controller_id=instance.node.site_deployment.controller.id).exists():
              raise DeferredException("Instance %s Private Network %s lacks ControllerNetwork object" % (instance, network.name))

        for controller_network in controller_networks:
            # Lenient exception - causes slow backoff
            if controller_network.network.template.translation == 'none':
                   if not controller_network.net_id:
                        raise DeferredException("Instance %s Private Network %s has no id; Try again later" % (instance, controller_network.network.name))
                   nics.append({"kind": "net", "value": controller_network.net_id, "network": controller_network.network})

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

        driver = self.driver.admin_driver(tenant='admin', controller=instance.node.site_deployment.controller)
        nets = driver.shell.neutron.list_networks()['networks']
        for net in nets:
            if net['name'] in network_templates:
                nics.append({"kind": "net", "value": net['id'], "network": None})

        if (not nics):
            for net in nets:
                if net['name']=='public':
                    nics.append({"kind": "net", "value": net['id'], "network": None})

        nics = self.sort_nics(nics)

        image_name = None
        controller_images = instance.image.controllerimages.all()
        controller_images = [x for x in controller_images if x.controller_id==instance.node.site_deployment.controller.id]
        if controller_images:
            image_name = controller_images[0].image.name
            logger.info("using image from ControllerImage object: " + str(image_name))

        if image_name is None:
            controller_driver = self.driver.admin_driver(controller=instance.node.site_deployment.controller)
            images = controller_driver.shell.glanceclient.images.list()
            for image in images:
                if image.name == instance.image.name or not image_name:
                    image_name = image.name
                    logger.info("using image from glance: " + str(image_name))

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

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

        availability_zone_filter = 'nova:%s'%host_filter
        instance_name = '%s-%d'%(instance.slice.name,instance.id)
        self.instance_name = instance_name

        userData = self.get_userdata(instance, pubkeys)
        if instance.userData:
            userData += instance.userData

        controller = instance.node.site_deployment.controller
        fields = {'endpoint':controller.auth_url,
                     'endpoint_v3': controller.auth_url_v3,
                     'domain': controller.domain,
                     'admin_user': instance.creator.email,
                     'admin_password': instance.creator.remote_password,
                     'project_name': instance.slice.name,
                     'tenant': instance.slice.name,
                     'tenant_description': instance.slice.description,
                     'name':instance_name,
                     'ansible_tag':instance_name,
                     'availability_zone': availability_zone_filter,
                     'image_name':image_name,
                     'flavor_name':instance.flavor.name,
                     'nics':nics,
                     'meta':metadata_update,
                     'user_data':r'%s'%escape(userData)}
        return fields


    def map_sync_outputs(self, instance, res):
	instance_id = res[0]['openstack']['OS-EXT-SRV-ATTR:instance_name']
        instance_uuid = res[0]['id']

	try:
            hostname = res[0]['openstack']['OS-EXT-SRV-ATTR:hypervisor_hostname']
            ip = socket.gethostbyname(hostname)
            instance.ip = ip
        except:
            pass

        instance.instance_id = instance_id
        instance.instance_uuid = instance_uuid
        instance.instance_name = self.instance_name
        instance.save()
	
	
    def map_delete_inputs(self, instance):
        controller_register = json.loads(instance.node.site_deployment.controller.backend_register)

        if (controller_register.get('disabled',False)):
            raise InnocuousException('Controller %s is disabled'%instance.node.site_deployment.controller.name)

        instance_name = '%s-%d'%(instance.slice.name,instance.id)
        controller = instance.node.site_deployment.controller
        input = {'endpoint':controller.auth_url,
                     'admin_user': instance.creator.email,
                     'admin_password': instance.creator.remote_password,
                     'project_name': instance.slice.name,
                     'tenant': instance.slice.name,
                     'tenant_description': instance.slice.description,
                     'name':instance_name,
                     'ansible_tag':instance_name,
                     'delete': True}
        return input
