# -*- coding: iso-8859-15 -*-


# Glasnost
# By: Odile Bénassy <obenassy@entrouvert.com>
#     Romain Chantereau <rchantereau@entrouvert.com>
#     Nicolas Clapiès <nclapies@easter-eggs.org>
#     Pierre-Antoine Dejace <padejace@entrouvert.be>
#     Thierry Dulieu <tdulieu@easter-eggs.com>
#     Florent Monnier <monnier@codelutin.com>
#     Cédric Musso <cmusso@easter-eggs.org>
#     Frédéric Péters <fpeters@entrouvert.be>
#     Benjamin Poussin <poussin@codelutin.com>
#     Emmanuel Raviart <eraviart@entrouvert.com>
#     Sébastien Régnier <regnier@codelutin.com>
#     Emmanuel Saracco <esaracco@easter-eggs.com>
#
# Copyright (C) 2000, 2001 Easter-eggs & Emmanuel Raviart
# Copyright (C) 2002 Odile Bénassy, Code Lutin, Thierry Dulieu, Easter-eggs,
#     Entr'ouvert, Frédéric Péters, Benjamin Poussin, Emmanuel Raviart,
#     Emmanuel Saracco & Théridion
# Copyright (C) 2003 Odile Bénassy, Romain Chantereau, Nicolas Clapiès,
#     Code Lutin, Pierre-Antoine Dejace, Thierry Dulieu, Easter-eggs,
#     Entr'ouvert, Florent Monnier, Cédric Musso, Ouvaton, Frédéric Péters,
#     Benjamin Poussin, Rodolphe Quiédeville, Emmanuel Raviart, Sébastien
#     Régnier, Emmanuel Saracco, Théridion & Vecam
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.


__doc__ = """Glasnost Proxy Tools"""

__version__ = '$Revision$'[11:-2]


import glasnost.proxy

from glasnost.common.tools import *
import glasnost.common.tools_new as commonTools
import glasnost.common.context as context

import imp
import sys
import os

_cachedProxiesByServerRole = {}


def getObjectLabelsTranslated(ids, destinationLanguages):
    handledRoles = context.getVar('knownRoles')
    labels = {}
    remainingIds = ids[:]
    while remainingIds:
        id = remainingIds[0]
        del remainingIds[0]
        serverHostNameAndPort, serverRole, localId = commonTools.splitId(id)
        proxyIds = [id]
        remainingIds2 = remainingIds[:]
        for id2 in remainingIds2:
            serverHostNameAndPort2, serverRole2, localId2 = commonTools.splitId(id2)
            if serverHostNameAndPort2 == serverHostNameAndPort \
               and serverRole2 == serverRole:
                proxyIds.append(id2)
                del remainingIds[remainingIds.index(id2)]
        proxy = getProxyForServerRole(serverRole)
        if proxy is None:
            continue
        serverId = commonTools.extractServerId(id)
        if serverId.startswith('glasnost://system/'):
            for pId in proxyIds:
                o = getObject(pId)
                labels[pId] = _(o.getLabel())
        else:
            labels.update(proxy.getObjectLabelsTranslated(
                    proxyIds, destinationLanguages, serverId = serverId))
    return labels


def getObjectLabelTranslated(objectId, destinationLanguages = None):
    if not destinationLanguages:
        destinationLanguages = context.getVar('readLanguages')
    if objectId.endswith('/__admin__'):
        return _('Admin')
    proxy = getProxy(objectId)
    if not proxy:
        return '[???]'
    return proxy.getObjectLabelTranslated(objectId, destinationLanguages)


def getObject(objectId):
    proxy = getProxy(objectId)
    return proxy.getObject(objectId)

def getProxy(id):
    context.push(dispatcherId = commonTools.extractDispatcherId(id))
    try:
        proxy = getProxyForServerRole(commonTools.extractRole(id))
    finally:
        context.pull()
    return proxy


def getProxyForServerRole(serverRole):
    """Return a proxy instance of a specific role.
    
    Keyword Argument:
    =================

    *serverRole*:
        The wanted proxy role string.
        
    Return:
    =======

    *None*:
        1. If the role is unknow.
        2. If there is no proxy avaible.

    *ProxyInstance*:
        The Proxy instance able to perform role server proxy.
    
    """

    if context.getVar('knownRoles') \
           and serverRole not in context.getVar('knownRoles'):
        return None

    serverRoleProxy = serverRole.replace('-', '')

    if _cachedProxiesByServerRole.has_key(serverRoleProxy):
        return _cachedProxiesByServerRole[serverRoleProxy]

    # Code inspired from the module knee.
    import glasnost.proxy
    proxyFileNames = os.listdir(glasnost.proxy.__path__[0])
    for proxyFileName in proxyFileNames:
        if proxyFileName.endswith('Proxy.py') \
               and proxyFileName[:-8].lower() == serverRoleProxy:
            proxyName = proxyFileName[:-3]
            if hasattr(glasnost.proxy, proxyName):
                module = getattr(glasnost.proxy, proxyName)
            else:
                moduleTriplet = imp.find_module(
                        proxyName, glasnost.proxy.__path__)
                try:
                    module = imp.load_module(
                            'glasnost.proxy.%s' % proxyName,
                            moduleTriplet[0], moduleTriplet[1],
                            moduleTriplet[2])
                finally:
                    if moduleTriplet[0]:
                        moduleTriplet[0].close()
                setattr(glasnost.proxy, proxyName, module)
            proxy = module.__dict__[proxyName]()
            break
    else:
        if 'ncards' in (context.getVar('knownRoles') or ['ncards']) and \
                serverRole not in ('ncards', 'sessions', 'translations'):
            ncardsProxy = getProxyForServerRole('ncards')
            try:
                ncard = ncardsProxy.getObjectByRole(serverRole)
            except (faults.MissingItem, faults.UnknownServerId):
                return None
            import NCardsProxy
            return NCardsProxy.getProxyClass(ncard)()
        return None
    _cachedProxiesByServerRole[serverRoleProxy] = proxy
    return _cachedProxiesByServerRole[serverRoleProxy]


def sortIds(ids):
    if ids is None:
        return []
    idsByServer = {}
    unknownIds = []
    for id in ids:
        serverHostNameAndPort, serverRole, localId = commonTools.splitId(id)
        serverId = commonTools.extractServerId(id)
        if not idsByServer.has_key(serverId):
            proxy = getProxyForServerRole(serverRole)
            if not proxy:
                unknownIds.append(id)
                continue
            idsByServer[serverId] = []
        idsByServer[serverId].append(id)
    serverIds = idsByServer.keys()
    # FIXME: Change the sort key.
    serverIds.sort()
    result = []
    for serverId in serverIds:
        serverNameAndPort, serverRole, mu = commonTools.splitId(serverId)
        proxy = getProxyForServerRole(serverRole)
        ids = idsByServer[serverId]
        sortedIds = proxy.sortObjectIds(ids, serverId = serverId, forceIds = 1)
        result += sortedIds
    result += unknownIds
    return result

