# Copyright (c) 2015 Hewlett-Packard Development Company, L.P.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import copy
import glanceclient.exc
from glanceclient.v1.images import Image as v1_image
import logging
import six

from searchlight.elasticsearch.plugins import openstack_clients
from searchlight import i18n

LOG = logging.getLogger(__name__)
_ = i18n._
_LW = i18n._LW


def serialize_glance_image(image):
    g_client = openstack_clients.get_glanceclient()
    using_v1 = False

    # If we're being asked to index an ID, retrieve the full image information
    if isinstance(image, basestring):
        image = g_client.images.get(image)

    # If a v1 image, convert to dict so we can iterate over its properties
    if isinstance(image, v1_image):
        using_v1 = True
        image = image.to_dict()
    else:
        image['visibility'] = 'public' if image.pop('is_public') else 'private'

    try:
        members = g_client.image_members.list(image['id'])
        if using_v1:
            members = [member.to_dict() for member in members]
    except glanceclient.exc.HTTPForbidden:
        LOG.warning(_LW("Could not list image members for %s; forbidden") %
                    image['id'])
        members = []
        pass

    fields_to_ignore = ['ramdisk_id', 'schema', 'kernel_id', 'file',
                        'locations']
    extra_properties = image.pop('properties', [])
    document = dict((k, v) for k, v in six.iteritems(image)
                    if k not in fields_to_ignore)

    document['members'] = [
        member['member'] for member in members
        if (member['status'] == 'accepted' and member['deleted'] == 0)]

    for kv in extra_properties:
        document[kv['name']] = kv['value']

    return document


def serialize_glance_metadef_ns(metadef_namespace):
    def _serialize_tag(tag):
        return {'name': tag['name']}

    def _serialize_property(name, property):
        serialized_prop = copy.deepcopy(property)
        serialized_prop['name'] = name
        if 'default' in serialized_prop:
            serialized_prop['default'] = str(serialized_prop['default'])
        if 'enum' in serialized_prop:
            serialized_prop['enum'] = map(str, serialized_prop['enum'])

        return serialized_prop

    def _serialize_object(obj):
        serialized_obj = {
            'name': obj['name'],
            'description': obj['description']
        }
        serialized_obj['properties'] = sorted([
            _serialize_property(name, property)
            for name, property in six.iteritems(obj.get('properties', {}))
        ])
        return serialized_obj

    def _serialize_res_type(rt):
        return {
            'name': rt['name']
        }

    # TODO(sjmc7): test this better
    incomplete = 'objects' not in metadef_namespace or \
                 'properties' not in metadef_namespace or \
                 'tags' not in metadef_namespace
    if incomplete:
        LOG.debug("Retrieving metadef namespace '%s'",
                  metadef_namespace['namespace'])
        g_client = openstack_clients.get_glanceclient()
        metadef_namespace = g_client.metadefs_namespace.get(
            metadef_namespace['namespace'])

    # The CIS code specifically serialized some fields rather than indexing
    # everything; do the same.
    namespace_fields = ('namespace', 'display_name', 'description',
                        'visibility', 'owner', 'protected')
    document = dict((f, metadef_namespace.get(f, None))
                    for f in namespace_fields)

    document['tags'] = sorted([
        _serialize_tag(tag) for tag in metadef_namespace.get('tags', [])
    ])
    document['properties'] = sorted([
        _serialize_property(name, property)
        for name, property in six.iteritems(
            metadef_namespace.get('properties', {}))
    ])
    document['objects'] = sorted([
        _serialize_object(obj) for obj in metadef_namespace.get('objects', [])
    ])
    document['resource_types'] = sorted([
        _serialize_res_type(rt)
        for rt in metadef_namespace.get('resource_type_associations', [])
    ])
    return document

@@ -1316,98 +1316,8 @@
 ct()
-%0A    else:%0A        image%5B'visibility'%5D = 'public' if image.pop('is_public') else 'private'
 %0A%0A  
@@ -1759,16 +1759,17 @@
 tions'%5D%0A
+%0A
     extr
@@ -1787,18 +1787,76 @@
 s = 
-image.pop(
+None%0A    if 'properties' in image:%0A        extra_properties = image%5B
 'pro
@@ -1863,21 +1863,17 @@
 perties'
-, %5B%5D)
+%5D
 %0A    doc
@@ -1972,24 +1972,68 @@
 to_ignore)%0A%0A
+    if image%5B'visibility'%5D != 'public':%0A    
     document
@@ -2048,16 +2048,20 @@
 s'%5D = %5B%0A
+    
         
@@ -2107,16 +2107,20 @@
         
+ 
+   
 if (memb
@@ -2176,16 +2176,45 @@
 == 0)%5D%0A%0A
+    if extra_properties:%0A    
     for 
@@ -2229,32 +2229,36 @@
 tra_properties:%0A
+    
         document

Fix glance plugin serializer errors