/*
 * The contents of this file are subject to the Mozilla Public License Version 1.1
 * (the "License"); you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at <http://www.mozilla.org/MPL/>.
 * 
 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
 * language governing rights and limitations under the License.
 * 
 * The Original Code is the Venice Web Communities System.
 * 
 * The Initial Developer of the Original Code is Eric J. Bowersox <erbo@silcom.com>,
 * for Silverwrist Design Studios.  Portions created by Eric J. Bowersox are
 * Copyright (C) 2002 Eric J. Bowersox/Silverwrist Design Studios.  All Rights Reserved.
 * 
 * Contributor(s): 
 */
package com.silverwrist.venice.ui.servlet;

import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.log4j.*;
import com.silverwrist.venice.core.*;
import com.silverwrist.venice.except.*;
import com.silverwrist.venice.ui.*;
import com.silverwrist.venice.ui.helpers.CookieControl;

class HttpVeniceUISession implements VeniceUISession
{
  /*--------------------------------------------------------------------------------
   * Static data members
   *--------------------------------------------------------------------------------
   */

  private static final String SESSION_ATTRIBUTE_STEM = "venice.vars.";

  private static Category logger = Category.getInstance(HttpVeniceUISession.class);

  /*--------------------------------------------------------------------------------
   * Attributes
   *--------------------------------------------------------------------------------
   */

  private HttpSession session;
  private UserContext user;
  private Cookie venice_cookie = null;

  /*--------------------------------------------------------------------------------
   * Constructor
   *--------------------------------------------------------------------------------
   */

  HttpVeniceUISession(HttpServletRequest request, HttpSession session, VeniceEngine engine)
      throws ServletException
  {
    this.session = session;   // save off the session variable
    try
    { // tell the engine to create us a user context
      user = engine.createUserContext(request.getRemoteAddr());

      // Did the user send a Venice authentication cookie?  If so, try to use it.
      Cookie[] cookies = request.getCookies();
      for (int i=0; (venice_cookie==null) && (i<cookies.length); i++)
      { // look for a Venice authentication cookie
	if (CookieControl.LOGIN_COOKIE.equals(cookies[i].getName()))
	  venice_cookie = cookies[i];

      } // end for
      
    } // end try
    catch (DataException e)
    { // context creation failed - remap the exception
      logger.error("Session creation failed: " + e.getMessage(),e);
      throw new ServletException("Session creation failed: " + e.getMessage(),e);

    } // end catch

  } // end constructor

  /*--------------------------------------------------------------------------------
   * Implementations from interface VeniceUISession
   *--------------------------------------------------------------------------------
   */

  public long getCreationTime()
  {
    return session.getCreationTime();

  } // end getCreationTime

  public String getID()
  {
    return session.getId();

  } // end getID

  public long getLastAccessedTime()
  {
    return session.getLastAccessedTime();

  } // end getLastAccessedTime

  public void setMaxInactiveInterval(int interval)
  {
    session.setMaxInactiveInterval(interval);

  } // end setMaxInactiveInterval

  public int getMaxInactiveInterval()
  {
    return session.getMaxInactiveInterval();

  } // end getMaxInactiveInterval

  public Object getAttribute(String name)
  {
    return session.getAttribute(SESSION_ATTRIBUTE_STEM + name);

  } // end getAttribute

  public Enumeration getAttributeNames()
  {
    Enumeration raw = session.getAttributeNames();
    ArrayList rc = new ArrayList();
    while (raw.hasMoreElements())
    { // look for attributes we've added
      String tmp = (String)(raw.nextElement());
      if (tmp.startsWith(SESSION_ATTRIBUTE_STEM))
	rc.add(tmp.substring(SESSION_ATTRIBUTE_STEM.length()));

    } // end while

    return Collections.enumeration(rc);

  } // end getAttributeNames

  public void setAttribute(String name, Object o)
  {
    session.setAttribute(SESSION_ATTRIBUTE_STEM + name,o);

  } // end setAttribute

  public void removeAttribute(String name)
  {
    session.removeAttribute(SESSION_ATTRIBUTE_STEM + name);

  } // end removeAttribute

  public void invalidate()
  {
    session.invalidate();

  } // end invalidate

  public UserContext getUser()
  {
    return user;

  } // end getUser

  public void setUser(UserContext user)
  {
    this.user = user;

  } // end setUser

  public void preprocess(RequestInput ri)
  {
    if (venice_cookie!=null)
    { // try to log in with the cookie
      try
      { // attempt authentication
	if (!(user.authenticateWithToken(venice_cookie.getValue())))
	{ // delete bogus cookie if it didn't work
	  CookieControl cctl = (CookieControl)(ri.queryService(CookieControl.class));
	  cctl.deleteCookie(CookieControl.LOGIN_COOKIE);

	} // end if

      } // end try
      catch (DataException de)
      { // it didn't work...
	CookieControl cctl = (CookieControl)(ri.queryService(CookieControl.class));
	cctl.deleteCookie(CookieControl.LOGIN_COOKIE);

      } // end catch

      venice_cookie = null;

    } // end if

  } // end preprocess

  /*--------------------------------------------------------------------------------
   * Implementations from interface HttpSessionBindingListener
   *--------------------------------------------------------------------------------
   */

  public void valueBound(HttpSessionBindingEvent event)
  { // do nothing
  } // end valueBound

  public void valueUnbound(HttpSessionBindingEvent event)
  {
    this.session = null;
    this.user = null;

  } // end valueUnbound

} // end class HttpVeniceUISession
