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 = SliceDeployment.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()

