# -*- coding: UTF-8 -*-


# Expression
# By: Frederic Peters <fpeters@entrouvert.com>
#     Emmanuel Raviart <eraviart@entrouvert.com>
#
# Copyright (C) 2004 Entr'ouvert, Frederic Peters & Emmanuel Raviart
#
# 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.


"""Identities Module"""


import errno

import libxml2

import expression.core.dataholders as dataholders
import expression.core.directories as directories
import expression.core.elements as elements
import expression.core.environs as environs
import expression.core.faults as faults
import expression.core.filesystems as filesystems
import expression.core.logs as logs
import expression.core.namespaces as namespaces
import expression.core.sessions as sessions
import expression.core.stations as stations
import expression.core.things as things

from persons import Person


class Identity(things.Thing):
    _session = None
    isAccount = False # Constant

    def deleteLassoIdentityDump(self):
        nodes = self.evaluateXpath("yep:lassoIdentityDump")
        if nodes:
            node = nodes[0]
            node.unlinkNode()
            node.freeNode()

    def deleteSessionToken(self):
        nodes = self.evaluateXpath("yep:sessionToken")
        if nodes:
            node = nodes[0]
            node.unlinkNode()
            node.freeNode()

    def getAccount(self):
        session = self.getSession()
        if session is None:
            return None
        return session.getAccount()

    def getLassoIdentityDump(self):
        nodes = self.evaluateXpath("yep:lassoIdentityDump")
        if nodes:
            return nodes[0].content
        else:
            return None

    def getLanguage(self):
        nodes = self.evaluateXpath("yep:language")
        if nodes:
            return nodes[0].content
        personLocation = self.personLocation
        if not personLocation:
            return None
        personHolder = self.walkToLocation(personLocation)
        person = personHolder.getRootElement()
        return person.getLanguage()

    def getPerson(self):
        if self.getPersonLocation():
            personHolder = self.walkToLocation(self.getPersonLocation())
            person = personHolder.getRootElement()
        elif self.evaluateXpath("yep:person"):
            person = Person(self.evaluateXpath("yep:person")[0], owner = self, previous = self)
        else:
            person = None
        return person

    def getPersonLocation(self):
        # FIXME: Replace with getPersonAbsolutePath() (see session.getAccountAbsolutePath() for an
        # example).
        nodes = self.evaluateXpath("yep:person/@src")
        if not nodes:
            return None
        return nodes[0].content

    def getSession(self):
        if self._session is None:
            sessionToken = self.getSessionToken()
            if sessionToken is None:
                self._session = "none"
            else:
                self._session = sessions.retrieveSession(sessionToken)
        if self._session == "none":
            return None
        return self._session

    def getSessionToken(self):
        nodes = self.evaluateXpath("yep:sessionToken")
        if not nodes:
            return None
        return nodes[0].content

    def getSimpleLabel(self):
        person = self.getPerson()
        if person is None:
            return _("Anonymous Identity #%s") % self.getDataHolder().localId
        else:
            return person.getSimpleLabel()

    def getUser(self):
        # Some times, users are stored in independant files; some times they are embedded inside
        # accounts.
        # => This method is needed to ease user retrieval.
        return self

    def getVoteToken(self, ballotBoxLocalId):
        votesNodes = self.evaluateXpath("yep:votes")
        if not votesNodes:
            return None
        votesNode = votesNodes[0]
        ballotBoxInternPath = "/ballot-boxes/%s" % ballotBoxLocalId
        tokenNodes = self.evaluateXpath(
            "yep:vote[yep:ballotBox/@src = '%s']/yep:token"
                % ballotBoxInternPath.replace("'", "&apos;"),
            votesNode)
        if not tokenNodes:
            return None
        return tokenNodes[0].content

    def setEnviron(self):
        baseEnviron = environs.get(_level = "handleHttpCommand")
        baseEnviron.setVar("user", self)

    def setLassoIdentityDump(self, lassoIdentityDump):
        self.setElementContent("yep:lassoIdentityDump", lassoIdentityDump)

    def setPersonLocation(self, personLocation):
        self.setElementAttribute("yep:person", "src", personLocation)

    def setSessionToken(self, sessionToken):
        self.setElementContent("yep:sessionToken", sessionToken)

    def setVoteToken(self, ballotBoxLocalId, voteToken):
        votesNodes = self.evaluateXpath("yep:votes")
        if votesNodes:
            votesNode = votesNodes[0]
        else:
            votesNode = self.node.newTextChild(None, "votes", None)
        ballotBoxInternPath = "/ballot-boxes/%s" % ballotBoxLocalId
        tokenNodes = self.evaluateXpath(
            "yep:vote[yep:ballotBox/@src = '%s']/yep:token"
                % ballotBoxInternPath.replace("'", "&apos;"),
            votesNode)
        if tokenNodes:
            tokenNode = tokenNodes[0]
        else:
            voteNode = votesNode.newTextChild(None, "vote", None)
            ballotBoxNode = voteNode.newTextChild(None, "ballotBox", None)
            ballotBoxNode.setProp("src", ballotBoxInternPath)
            tokenNode = voteNode.newTextChild(None, "token", None)
        tokenNode.setContent(voteToken)
        # Note: Don't use setContent, because for some nodes it tries to
        # convert entities references.
        # tokenNode.setContent(voteToken)
        if tokenNode.children is not None:
            childNode = tokenNode.children
            childNode.unlinkNode()
            childNode.freeNodeList()
        tokenNode.addChild(tokenNode.doc.newDocText(voteToken))

    personLocation = property(getPersonLocation, setPersonLocation)
    simpleLabel = property(getSimpleLabel)


elements.registerElement(
    namespaces.yep.uri, "identity", Identity,
    "http://www.entrouvert.org/expression/schemas/User.xsd",
    "http://www.entrouvert.org/expression/descriptions/Identity.xml")
elements.registerElement(
    namespaces.yep.uri, "user", Identity,
    "http://www.entrouvert.org/expression/schemas/User.xsd",
    "http://www.entrouvert.org/expression/descriptions/Identity.xml")
