import os
import base64
from collections import defaultdict
from django.db.models import F, Q
from planetstack.config import Config
from observer.openstacksyncstep import OpenStackSyncStep
from core.models import Deployment
from core.models import Image, ImageDeployment
from util.logger import Logger, logging

logger = Logger(level=logging.INFO)

class SyncImageDeployment(OpenStackSyncStep):
    provides=[ImageDeployment]
    requested_interval=0

    def fetch_pending(self, deleted):
        if (deleted):
            return []
         # smbaker: commented out automatic creation of ImageDeployment as
         #    as they will now be configured in GUI. Not sure if this is
         #    sufficient.

#        # ensure images are available across all deployments
#        image_deployments = ImageDeployment.objects.all()
#        image_deploy_lookup = defaultdict(list)
#        for image_deployment in image_deployments:
#            image_deploy_lookup[image_deployment.image].append(image_deployment.deployment)
#
#        all_deployments = Deployment.objects.all()
#        for image in Image.objects.all():
#            expected_deployments = all_deployments
#            for expected_deployment in expected_deployments:
#                if image not in image_deploy_lookup or \
#                  expected_deployment not in image_deploy_lookup[image]:
#                    id = ImageDeployment(image=image, deployment=expected_deployment)
#                    id.save()

        # now we return all images that need to be enacted
        return ImageDeployment.objects.filter(Q(enacted__lt=F('updated')) | Q(enacted=None))

    def sync_record(self, image_deployment):
        logger.info("Working on image %s on deployment %s" % (image_deployment.image.name, image_deployment.deployment.name))
        driver = self.driver.admin_driver(deployment=image_deployment.deployment.name)
        images = driver.shell.glance.get_images()
        glance_image = None
        for image in images:
            if image['name'] == image_deployment.image.name:
                glance_image = image
                break
        if glance_image:
            logger.info("Found image %s on deployment %s" % (image_deployment.image.name, image_deployment.deployment.name))
            image_deployment.glance_image_id = glance_image['id']
        elif image_deployment.image.path:
            image = {
                'name': image_deployment.image.name,
                'is_public': True,
                'disk_format': 'raw',
                'container_format': 'bare',
                'file': image_deployment.image.path,
            }

            logger.info("Creating image %s on deployment %s" % (image_deployment.image.name, image_deployment.deployment.name))

            glance_image = driver.shell.glanceclient.images.create(name=image_deployment.image.name,
                                                                   is_public=True,
                                                                   disk_format='raw',
                                                                   container_format='bare')
            glance_image.update(data=open(image_deployment.image.path, 'rb'))

            # While the images returned by driver.shell.glance.get_images()
            #   are dicts, the images returned by driver.shell.glanceclient.images.create
            #   are not dicts. We have to use getattr() instead of [] operator.
            if not glance_image or not getattr(glance_image,"id",None):
                raise Exception, "Add image failed at deployment %s" % image_deployment.deployment.name
            image_deployment.glance_image_id = getattr(glance_image, "id")
        image_deployment.save()
