# -*- coding: utf-8 -*-
"""
w2lapp.session: The session handling thingy

web2ldap - a web-based LDAP Client,
see http://www.web2ldap.de for details

(c) by Michael Stroeder <michael@stroeder.com>

This module is distributed under the terms of the
GPL (GNU GENERAL PUBLIC LICENSE) Version 2
(see http://www.gnu.org/copyleft/gpl.html)
"""

import sys,time,\
       pyweblib.session,ldapsession,w2lapp.cnf


class Session(pyweblib.session.WebSession):

  def renameSession(self,old_sid,env):
    session_data = self.retrieveSession(old_sid,env)
    new_sid = self.newSession(env)
    self.storeSession(new_sid,session_data)
    pyweblib.session.WebSession.deleteSession(self,old_sid)
    return new_sid

  def deleteSession(self,sid):
    try:
      ls_local = self.sessiondict[sid][1]
    except KeyError:
      pass
    else:
      if isinstance(ls_local,ldapsession.LDAPSession):
        ls_local.unbind()
    pyweblib.session.WebSession.deleteSession(self,sid)


class CleanUpThread(pyweblib.session.CleanUpThread):
  """
  Thread class for clean-up thread

  Mainly it overrides pyweblib.session.CleanUpThread.run()
  to call ldapSession.unbind().
  """

  def run(self):
    """Thread function for cleaning up session database"""
    while not self._stop_event.isSet():
      try:
        current_time = time.time()
        sessiondict_keys = [
          sid
          for sid in self._sessionInstance.sessiondict.keys()
          if not sid.startswith('__')
        ]
        for session_id in sessiondict_keys:
          try:
            session_timestamp,ldapSession = self._sessionInstance.sessiondict[session_id]
          except KeyError:
            # Avoid race condition. The session might have been
            # deleted in the meantime. But make sure everything is deleted.
            self._sessionInstance.deleteSession(session_id)
          else:
            # Check expiration time
            if session_timestamp+self._sessionInstance.expireRemove<current_time:
              # Remove expired session
              self._sessionInstance.deleteSession(session_id)
              self._removed+=1
      except:
        # Catch all exceptions to avoid thread being killed.
        if __debug__:
          traceback.print_exc()
        pass

      # Sleeping until next turn
      self._stop_event.wait(self._interval)

    return # CleanUpThread.run()


########################################################################
# Initialize web session object
########################################################################

session = Session(
  expireDeactivate=w2lapp.cnf.misc.session_remove,
  expireRemove=w2lapp.cnf.misc.session_remove,
  crossCheckVars = w2lapp.cnf.misc.session_checkvars,
  maxSessionCount = w2lapp.cnf.misc.session_limit,
)

cleanUpThread = CleanUpThread(session,interval=5)
