#!/usr/bin/python
#

import os
from .msgL10n import L10nMessage, MessageMetadata, Catalog
from .json_utils import Serializable, JsonSerializer

DEFAULT_LOCALE = 'en'

INSTALL_VMSG_FILE_NAME = 'cis_install_catalog.vmsg'

_theCatalog = None

def configure(localeDir, locale=DEFAULT_LOCALE):
    # pylint: disable=W0613
    '''Configures the i18n module. The method lists the locale dir to find the
    proper localization catalog for given locale. The module should be configured
    first before any localizedString usage.

    @param localeDir: The directory where the localization catalog is located.
    @type localeDir: str

    @param locale: current locale
    @param locale: str
    '''
    enVmsgPath = os.path.join(localeDir, DEFAULT_LOCALE,
                                  INSTALL_VMSG_FILE_NAME)
    loVmsgPath = os.path.join(localeDir, locale,
                                  INSTALL_VMSG_FILE_NAME)
    global _theCatalog
    _theCatalog = Catalog(enVmsgPath, loVmsgPath)

class LocalizableMessage(Serializable):
    def __init__(self, l10nMsg):
        self.l10nMsg = l10nMsg

    def __str__(self):
        return self.l10nMsg.translate(_theCatalog)

    def __serialize__(self):
        return self.l10nMsg.jsonEncode(_theCatalog)

    def __localizableMessage__(self):
        return self.l10nMsg

    @classmethod
    def __deserialize__(cls, jObject):
        l10nMsg = L10nMessage.jsonDecode(jObject)
        return cls(l10nMsg)

    def __eq__(self, other):
       if not isinstance(other, LocalizableMessage):
           return False
       return self.l10nMsg.msgMeta.msgId ==\
           other.l10nMsg.msgMeta.msgId

    def __ne__(self, other):
       return not self.__eq__(other)

    def __hash__(self):
       return hash(self.l10nMsg.msgMeta.msgId)

def localizedString(msgMeta, args=None):
    '''Translates message based on the current locale.

    @param msgMeta: a message metadata definition that
                    includes an id and a format text. See msgL10n.py
    @type  msgKey: MessageMetadata

    @param args: Message arguments which need to be substituted.

    @return: A serializable and localizable message object
    @rtype: LocalizableMessage
    '''
    l10nMsg = L10nMessage(msgMeta, args)
    return LocalizableMessage(l10nMsg)

def msgMetadata(msgId, formatText):
    '''Wrapper function that contructs a MessageMetadata
    object. Please see the msgL10n module for the definition of
    the MessageMetadata class
    @param msgId: The message id is dot seperated string representation
                  such as framework.esx.incompatible.
    @param formatText: The format text is the standard python string format.
    @return: a MessageMetadata object
    @rtypoe: MessageMetadata
    '''
    return MessageMetadata(msgId, formatText)

def RunTests():
    _T = msgMetadata
    esx_incompatible = _T('framework.esx.incompatible',
            'ESX host %(host)s of version %(version)2.1f is not compatible')

    # You should normally not do this:
    #     esx_incompatible % {'host' : 'zhangv-esx', 'version' : 4.1 }
    # though it is probably OK to use it for log output.

    # You should create a L10nMessage object
    #     message = L10nMessage(esx_incompatible,
    #                              {'host' : 'zhangv-esx', 'version' : 4.1 })
    # Pass the message to UI by calling the jsonEncode or jsonEncodeStr() method

    # At some point, UI can translate the entire message by looking up the
    # message id in a .vmsg file in a proper locale, and then format the
    # translated text using the paramters carried in the message (now part of
    # the encoded json string).

    invalid_host_creds = _T('framework.source_vcva.host.cannot_authenticate',
            'Failed to authenticate into the VC/ESX host %s that manages'
            ' the source VCVA %s')

    out_of_diskspace = _T('framework.export.diskspace',
                          'Out of export disk space(100%% used)')

    stack_overflow = _T('framework.stack_overflow',
                        'stack overflow')

    framework_internal = _T('framework.internal',
                "Encountered an internal error,\n\tDetails: '%s'")

    msg1 = localizedString(esx_incompatible,
                          {'host' : 'zhangv-esx',
                           'version' : 4.1})

    msg2 = localizedString(invalid_host_creds,
                          ('zhangv-esx', 'zhangv-vcva'))

    msg3 = localizedString(out_of_diskspace)

    msg4_param = localizedString(stack_overflow)

    msg4 = localizedString(framework_internal, msg4_param)

    jsonSerializer = JsonSerializer()

    for msg in (msg1, msg2, msg3, msg4):
        smsgEncoded = jsonSerializer.serialize(msg)
        smsgDecoded = jsonSerializer.deserialize(smsgEncoded)
        print(jsonSerializer.serialize(smsgDecoded))

if __name__ == '__main__':
    RunTests()
