#include "types.h"
#include "mpool.h"
#include "tktree.h"
#include "clstree.h"
#include "sha1.h"
#include "listen.h"
#include "ssl_conf.h"
#include "rovm.h"

#include "thread.h"
#include "thread_mutex.h"
#include "thread_cond.h"

#include "mpm_worker_fdqueue.h"
#include "mpm_worker_pod.h"
#include "mpm_worker.h"

#include "connection.h"
#include "request.h"
#include "proc_rc.h"

#include "log.h"
#include "common.h"
#include "ticket.h"

/*  _________________________________________________________________
**
**  Session Cache: Common Abstraction Layer
**  _________________________________________________________________
*/

void 
ssl_scache_init (struct rovm *r, apr_pool_t *p)
{
  SSLModConfigRec *mc = myModConfig (r);
  
  /*
   * Warn the user that he should use the session cache.
   * But we can operate without it, of course.
   */
  if (mc->nSessionCacheMode == SSL_SCMODE_UNSET) 
    {
      rovm_log (NULL, ROVMLOG_WARNING, ROVMLOG_MARK, 
                "Init: Session Cache is not configured "
                "[hint: SSLSessionCache]");
      mc->nSessionCacheMode = SSL_SCMODE_NONE;
      return;
    }
  
  if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
    ssl_scache_dbm_init(r, p);
#ifdef HAVE_DISTCACHE
  else if (mc->nSessionCacheMode == SSL_SCMODE_DC)
    ssl_scache_dc_init(r, p);
#endif
  else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB) 
    ssl_scache_shmcb_init (r, p);
}

void
ssl_scache_kill (struct rovm *r)
{
  SSLModConfigRec *mc = myModConfig (r);
  
  if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
    ssl_scache_dbm_kill (r);
  else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB)
    ssl_scache_shmcb_kill (r);
#ifdef HAVE_DISTCACHE
  else if (mc->nSessionCacheMode == SSL_SCMODE_DC)
    ssl_scache_dc_kill(r);
#endif
  return;
}

BOOL 
ssl_scache_store (struct rovm *r, UCHAR *id, int idlen, time_t expiry, SSL_SESSION *sess)
{
  SSLModConfigRec *mc = myModConfig(r);
  BOOL rv = FALSE;
  
  if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
    rv = ssl_scache_dbm_store(r, id, idlen, expiry, sess);
  else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB)
    rv = ssl_scache_shmcb_store(r, id, idlen, expiry, sess);
#ifdef HAVE_DISTCACHE
  else if (mc->nSessionCacheMode == SSL_SCMODE_DC)
    rv = ssl_scache_dc_store(r, id, idlen, expiry, sess);
#endif
  return rv;
}

SSL_SESSION *
ssl_scache_retrieve(struct rovm *r, UCHAR *id, int idlen)
{
  SSLModConfigRec *mc = myModConfig(r);
  SSL_SESSION *sess = NULL;
  
  if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
    sess = ssl_scache_dbm_retrieve(r, id, idlen);
  else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB)
    sess = ssl_scache_shmcb_retrieve(r, id, idlen);
#ifdef HAVE_DISTCACHE
  else if (mc->nSessionCacheMode == SSL_SCMODE_DC)
    sess = ssl_scache_dc_retrieve(r, id, idlen);
#endif
  return sess;
}

void
ssl_scache_remove(struct rovm *r, UCHAR *id, int idlen)
{
  SSLModConfigRec *mc = myModConfig(r);
  
  if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
    ssl_scache_dbm_remove(r, id, idlen);
  else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB)
    ssl_scache_shmcb_remove(r, id, idlen);
#ifdef HAVE_DISTCACHE
  else if (mc->nSessionCacheMode == SSL_SCMODE_DC)
    ssl_scache_dc_remove(r, id, idlen);
#endif
  return;
}
