"""
$URL: svn+ssh://svn.mems-exchange.org/repos/trunk/dulcinea/lib/persistent_session.py $
$Id: persistent_session.py 28244 2006-04-20 20:52:09Z dbinger $

Provides persistent versions of Quixote's session management classes.
"""
from datetime import datetime
from dulcinea.attachable import Attachable
from dulcinea.common import get_publisher
from dulcinea.user import DulcineaUser
from durus.persistent import Persistent
from durus.persistent_dict import PersistentDict
from durus.persistent_list import PersistentList
from qp.lib.spec import subclass, mapping, sequence, spec, string
from quixote.session import Session as QuixoteSession
from quixote.session import SessionManager as QuixoteSessionManager

def get_session_manager():
    return get_publisher().get_connection().get_root()['session_manager']

class DulcineaSession (Persistent, QuixoteSession, Attachable):
    user_is = spec(
        DulcineaUser,
        "(overrides Session's attribute for stronger typing) "
        "the user object used for access control checks.  Usually "
        "user == actual_user, but when an admin user is acting as some other "
        "user, user is the person being impersonated, and actual_user is "
        "the person actually doing the work (ie.  the admin user)")
    actual_user_is = DulcineaUser
    last_user_is = DulcineaUser
    _form_tokens_is = sequence(string, PersistentList)
    _remote_address_is = (None, string)
    _access_time_is = float
    id_is = string
    _creation_time_is = float

    def __init__ (self, *args):
        if args:
            QuixoteSession.__init__(self, *args)
        Attachable.__init__(self)
        self.clear_authentication()
        self.last_user = self.user
        self._form_tokens = PersistentList()

    def clear_app_state(self):
        """Override to clear any session data when acting as another user
        """
        pass

    def has_info (self):
        return bool(self._form_tokens or self.get_owner())

    def set_actual_user (self, user):
        print 'set_actual_user is deprecated'
        self.set_authenticated(user)

    def set_user(self, user):
        print 'set_user is deprecated'
        self.set_effective_user(user)

    def get_effective_user(self):
        return self.user

    def get_authentication_time(self):
        return datetime.fromtimestamp(self._creation_time)

    def get_access_time(self):
        return datetime.fromtimestamp(self._access_time)

    def set_authenticated(self, user):
        self.user = self.actual_user = user
        if user:
            self.last_user = user

    def set_effective_user(self, user):
        return QuixoteSession.set_user(self, user)

    def get_owner(self):
        return self.last_user

    def clear_authentication(self):
        null_user = get_publisher().get_users().get('')
        self.user = null_user
        self.actual_user = null_user

class DulcineaSessionManager (Persistent, QuixoteSessionManager):

    sessions_is = mapping({string:DulcineaSession}, PersistentDict)
    session_class_is = subclass(DulcineaSession)

    ACCESS_TIME_RESOLUTION = 900 # in seconds (don't dirty the session on
                                 # every hit)

    def __init__ (self, session_class=DulcineaSession, session_mapping=None):
        if session_mapping is None:
            session_mapping = PersistentDict()
        QuixoteSessionManager.__init__(self,
                                       session_class=session_class,
                                       session_mapping=session_mapping)

    def forget_changes (self, session):
        get_publisher().abort()

    def commit_changes (self, session):
        get_publisher().commit()





