import os
import json
import base64
from django.db.models import F, Q
from planetstack.config import Config
from ec2_observer.syncstep import SyncStep
from core.models.sliver import Sliver
from core.models.slice import SlicePrivilege, SliceDeployment
from core.models.network import Network, NetworkSlice, NetworkDeployments
from util.logger import Logger, logging
from ec2_observer.awslib import *
from core.models.site import *
from core.models.slice import *
from ec2_observer.creds import *
import pdb

logger = Logger(level=logging.INFO)

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

    def fetch_pending(self, deletion):
        if deletion:
            object_source = Sliver.deleted_objects
        else:
            object_source = Sliver.objects

        all_slivers = object_source.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))
        my_slivers = [] 

        for sliver in all_slivers:
            sd = SliceDeployments.objects.filter(Q(slice=sliver.slice))
            if (sd):
                if (sd.deployment.name=='Amazon EC2'):
                    my_slivers.append(sliver)
            if (sliver.node.deployment.name=='Amazon EC2'):
                my_slivers.append(sliver)
        return my_slivers

    def delete_record(self, sliver):
        user = sliver.creator
        e = get_creds(user=user, site=user.site)
        result = aws_run('ec2 terminate-instances --instance-ids=%s'%sliver.instance_id, env=e)

    def sync_record(self, sliver):
        logger.info("sync'ing sliver:%s deployment:%s " % (sliver, sliver.node.deployment))

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

            if sliver.creator.public_key:
                pubkeys.append(sliver.creator.public_key)

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

            # netowrks
            # include all networks available to the slice and/or associated network templates
            #nics = []
            #networks = [ns.network for ns in NetworkSlice.objects.filter(slice=sliver.slice)]  
            #network_deployments = NetworkDeployments.objects.filter(network__in=networks, 
                                                                    #deployment=sliver.node.deployment)
            # Gather private networks first. This includes networks with a template that has
            # visibility = private and translation = none
            #for network_deployment in network_deployments:
            #   if network_deployment.network.template.visibility == 'private' and \
            #      network_deployment.network.template.translation == 'none': 
            #       nics.append({'net-id': network_deployment.net_id})
    
            # now include network template
            #network_templates = [network.template.sharedNetworkName for network in networks \
            #                    if network.template.sharedNetworkName]
            #for net in driver.shell.quantum.list_networks()['networks']:
            #   if net['name'] in network_templates: 
            #       nics.append({'net-id': net['id']}) 
            # look up image id

            instance_type = sliver.node.name.rsplit('.',1)[0]

            # Bail out of we don't have a key
            key_name = sliver.creator.email.lower().replace('@', 'AT').replace('.', '')
            u = sliver.creator
            s = u.site
            e = get_creds(user=u, site=s)
            key_sig = aws_run('ec2 describe-key-pairs', env=e)
            ec2_keys = key_sig['KeyPairs']
            key_found = False
            for key in ec2_keys:
                if (key['KeyName']==key_name):
                    key_found = True
                    break

            if (not key_found):
                # set backend_status
                raise Exception('Will not sync sliver without key')

            image_id = sliver.image.path
            instance_sig = aws_run('ec2 run-instances --image-id %s --instance-type %s --count 1 --key-name %s --placement AvailabilityZone=%s'%(image_id,instance_type,key_name,sliver.node.site.name), env=e)
            sliver.instance_id = instance_sig['Instances'][0]['InstanceId']
            sliver.save()
            state = instance_sig['Instances'][0]['State']['Code']
            if (state==16):
                sliver.ip = instance_sig['Instances'][0]['PublicIpAddress']
                sliver.save()
            else:
                # This status message should go into backend_status
                raise Exception('Waiting for instance to start')
        else:
            ret = aws_run('ec2 describe-instances --instance-ids %s'%sliver.instance_id, env=e)
            state = ret['Reservations'][0]['Instances'][0]['State']['Code']
            if (state==16):
                sliver.ip = ret['Reservations'][0]['Instances'][0]['PublicIpAddress']
                sliver.save()

