# -*- 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 Ballots Proxy"""

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


import glasnost.common.context as context
import glasnost.common.tools_new as commonTools

from DispatcherProxy import callServer, getApplicationToken
from ObjectsProxy import Proxy
from tools import *
import VotesProxy # Do not remove!


# Note: By convention, the elections and the votes are always stored on the
# same virtual host (same dispatcher id).
# In the same way, the ballots virtual host is the same as the elections and
# the votes.
# By contrast, the voters are not always on the same virtual host as the
# elections or the votes.


class BallotsProxy(Proxy):
    serverRole = 'ballots'

    def abstainForVote(self, electionId):
        userToken = context.getVar('userToken', default = '')
        serverId = self.getServerId(serverId = electionId)
        callServer(
            serverId,
            'abstainForVote',
            [serverId, getApplicationToken(), userToken, electionId])

    def canGetVoteVoterId(self, voteId):
        userToken = context.getVar('userToken', default = '')
        serverId = self.getServerId(serverId = voteId)
        return callServer(
            serverId,
            'canGetVoteVoterId',
            [serverId, getApplicationToken(), userToken, voteId])

    def getElectionIdFromToken(self, electionToken, serverId = None):
        userToken = context.getVar('userToken', default = '')
        serverId = self.getServerId(serverId = serverId)
        return callServer(
            serverId,
            'getElectionIdFromToken',
            [serverId, getApplicationToken(), userToken, electionToken])

    def getElectionVotes(self, voteTokens, electionVoterIds):
        if not voteTokens:
            return []
        if electionVoterIds is None:
            electionVoterIds = []
        userToken = context.getVar('userToken', default = '')
        serverId = self.getServerId(serverId = voteTokens[0])
        votesImport = callServer(
            serverId,
            'getElectionVotes',
            [serverId, getApplicationToken(), userToken, voteTokens,
             electionVoterIds])
        votes = []
        for voteImport in votesImport:
            vote = commonTools.importThing(voteImport)
            votes.append(vote)
        return votes

    def getElectionWeightings(self, voteTokens, weightingsById):
        if not voteTokens:
            return {}
        if weightingsById is None:
            return {}
        userToken = context.getVar('userToken', default = '')
        serverId = self.getServerId(serverId = voteTokens[0])
        return callServer(
            serverId,
            'getElectionWeightings',
            [serverId, getApplicationToken(), userToken, voteTokens,
             weightingsById])

    def getVote(self, voteId):
        userToken = context.getVar('userToken', default = '')
        serverId = self.getServerId(serverId = voteId)
        voteImport = callServer(
            serverId,
            'getVote',
            [serverId, getApplicationToken(), userToken, voteId])
        if voteImport == 'secret':
            vote = voteImport
        else:
            vote = commonTools.importThing(voteImport)
        return vote

    def getVoteFromToken(self, voteToken):
        if voteToken == 'secret':
            return voteToken
        userToken = context.getVar('userToken', default = '')
        serverId = self.getServerId(serverId = voteToken)
        voteImport = callServer(
            serverId,
            'getVoteFromToken',
            [serverId, getApplicationToken(), userToken, voteToken])
        if voteImport == 'secret':
            vote = voteImport
        else:
            vote = commonTools.importThing(voteImport)
        return vote

    def getVotesFromTokens(self, voteTokens):
        userToken = context.getVar('userToken', default = '')
        if voteTokens is None:
            voteTokens = {}
        dispatcherIds = []
        votes = {}
        for electionId, voteToken in voteTokens.items():
            if voteToken == 'secret':
                votes[electionId] = voteToken
            else:
                dispatcherId = commonTools.extractDispatcherId(voteToken)
                if not dispatcherId in dispatcherIds:
                    dispatcherIds.append(dispatcherId)
        for dispatcherId in dispatcherIds:
            serverVoteTokens = {}
            for electionId, voteToken in voteTokens.items():
                if voteToken.startswith(dispatcherId):
                    serverVoteTokens[electionId] = voteToken
            serverId = self.getServerId(serverId = dispatcherId)
            votesImport = callServer(
                serverId,
                'getVotesFromTokens',
                [serverId, getApplicationToken(), userToken, serverVoteTokens])
            for electionId, voteImport in votesImport.items():
                if voteImport == 'secret':
                    vote = voteImport
                else:
                    vote = commonTools.importThing(voteImport)
                votes[electionId] = vote
        return votes

    def getVotesProxy(self):
        return getProxyForServerRole('votes')

    def getVoteVoterId(self, voteId):
        userToken = context.getVar('userToken', default = '')
        serverId = self.getServerId(serverId = voteId)
        return callServer(
            serverId,
            'getVoteVoterId',
            [serverId, getApplicationToken(), userToken, voteId])

    def isVoteSecret(self, voteToken):
        userToken = context.getVar('userToken', default = '')
        serverId = self.getServerId(serverId = voteToken)
        return callServer(
            serverId,
            'isVoteSecret',
            [serverId, getApplicationToken(), userToken, voteToken])

    def vote(self, electionId, vote):
        userToken = context.getVar('userToken', default = '')
        serverId = self.getServerId(serverId = electionId)
        voteExport = vote.exportToXmlRpc()
        return callServer(
            serverId,
            'vote',
            [serverId, getApplicationToken(), userToken, electionId,
             voteExport])

