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.deployment import Deployment
from core.models.image 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):
        # 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()
