#
# Copyright (c) 2010 Red Hat, Inc.
#
# 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 sys

# Note that in this case we can't just use the io.StringIO class
# because the code generated by generateDS.py expects to be able
# to write strings to the output, and the io.StringIO class only
# accepts Unicode strings.
try:
    from StringIO import StringIO
except ImportError:
    from io import StringIO

from ovirtsdk.infrastructure import common
from ovirtsdk.utils.reflectionhelper import ReflectionHelper
from ovirtsdk.xml import params

class ParseHelper():
    '''Provides parsing capabilities'''

    @staticmethod
    def toXml(obj):
        """Convert object to corresponding XML representation."""

        # The given object may be a broker. If it is then we need to extract
        # the actual entity object.
        entity = obj
        if ReflectionHelper.isModuleMember(sys.modules['ovirtsdk.infrastructure.brokers'],
                                           type(obj)) and hasattr(obj, 'superclass'):
            entity = obj.superclass

        # Find the XML tag corresponding to the entity type. There won't be
        # such a tag if the type doesn't have a top level element definition
        # inside the XML schema, as those can't be used as root elements and
        # aren't accepted or generated by the RESTAPI server.
        entity_type = type(entity)
        entity_tag = params._tag_for_type.get(entity_type)
        if entity_tag is None:
            raise Exception(
                "The entity type \"%s\" can't be converted to XML because "
                "according to the XML schema it hasn't a top level element "
                "definition, thus it can't be used as the root of a valid "
                "XML document." % entity_type.__name__
            )

        # Generate the XML document:
        output = StringIO()
        entity.export_(output, 0, name_=entity_tag)
        return output.getvalue().encode("utf-8")

    @staticmethod
    def getXmlWrapperType(type_name):
        tn = type_name.lower()
        for k, v in params._rootClassMap.items():
            if v.__name__.lower() == tn \
             or k.lower() == tn \
             or k.replace("_", "") == tn:
                return v.__name__
        return type_name

    @staticmethod
    def getXmlTypeInstance(type_name):
        tn = type_name.lower()
        for k, v in params._rootClassMap.items():
            if v.__name__.lower() == tn:
                return k
        return type_name

    @staticmethod
    def getXmlType(type_name):
        if type_name and type_name != '':
            tn = type_name.lower()
            items = params._rootClassMap.items()
            for k, v in items:
                if v.__name__.lower() == tn or k.lower() == tn:
                    return v
        return None

    @staticmethod
    def getSingularXmlTypeInstance(type_name):
        instance = ParseHelper.getXmlTypeInstance(type_name)
        if instance.endswith('s'):
            return instance[0 : len(instance) - 1]
        return instance

    @staticmethod
    def toType(fromItem, toType, **kwargs):
        '''Encapsulates the entity with the broker instance.'''
        return toType(fromItem, **kwargs)

    @staticmethod
    def toCollection(toType, fromItems=[], **kwargs):
        '''Encapsulates entities collection with the broker decorator collection.'''
        new_coll = []
        for item in fromItems:
            new_coll.append(ParseHelper.toType(item, toType, **kwargs))
        return new_coll

    @staticmethod
    def toSubType(fromItem, toType, parent, **kwargs):
        '''Encapsulates the sub-entity with the broker instance.'''
        return toType(parent, fromItem, **kwargs)

    @staticmethod
    def toSubTypeFromCollection(toType, parent, fromItems=[], **kwargs):
        '''Encapsulates the sub-entity collection element with the broker instance.'''
        if(fromItems is not None and len(fromItems) > 0):
            return toType(parent, fromItems[0], **kwargs)

    @staticmethod
    def toTypeFromCollection(toType, fromItems=[], **kwargs):
        '''Encapsulates the entity collection element with the broker instance.'''
        #return toType(fromItems[0]) if(fromItems is not None and len(fromItems) > 0) else None
        return toType(fromItems[0] if(fromItems is not None and len(fromItems) > 0) \
                                   else None, **kwargs)

    @staticmethod
    def toSubCollection(toType, parent, fromItems=[], **kwargs):
        '''Encapsulates the sub-entities collection with the broker instance collection.'''
        new_coll = []
        for fromItem in fromItems:
            new_coll.append(ParseHelper.toSubType(fromItem, toType, parent, **kwargs))
        return new_coll
