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, ImageDeployments
from util.logger import Logger, logging

logger = Logger(level=logging.INFO)

class SyncImageDeployments(OpenStackSyncStep):
    provides=[ImageDeployments]
    requested_interval=0

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

#        # ensure images are available across all deployments
#        image_deployments = ImageDeployments.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 = ImageDeployments(image=image, deployment=expected_deployment)
#                    id.save()

        # now we return all images that need to be enacted
        return ImageDeployments.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()
