// Package 
package gov.va.med.esr.ui.admin.action;

// Java Classes
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Hashtable;
import java.util.Iterator;

// Library Classes
import org.apache.commons.lang.Validate;
import weblogic.servlet.internal.WebAppServletContext;
import weblogic.servlet.internal.session.SessionContext;

// ESR Classes
import gov.va.med.esr.ui.common.action.AbstractAction;
import gov.va.med.esr.common.model.lookup.Capability;

/**
 * Struts action support class that will aid in working with user session information.
 *
 * @author Andrew Pach
 * @version: 3.0
 */
public class UserSessionsAbstractAction extends AbstractAction
{
    // List of administrator permissions
    protected static String[] administratorPermissions =
        {Capability.LOCAL_ADMINISTRATOR.getName(), Capability.ADMINISTRATOR.getName()};

    /**
     * A default constructor
     */
    public UserSessionsAbstractAction()
    {
        super();
    }

    /**
     * Gets a user session based on the session Id.
     *
     * @param request A http request
     * @param id The session Id to get
     * @return The session or null if it could not be found.
     */
    protected HttpSession getSessionById(HttpServletRequest request, String id)
    {
        // Ensure we have a session Id
        Validate.notEmpty(id, "Session Id can not be empty.");

        // Get the open list of sessions
        Hashtable sessionTable = getSessions(request);

        // Iterate through the sessions
        for (Iterator iterator = sessionTable.values().iterator(); iterator.hasNext();)
        {
            // Get a session
            HttpSession session = (HttpSession)iterator.next();
            if (id.equals(session.getId()))
            {
                return session;
            }
        }

        // The session with the passed in Id couldn't so return null
        return null;
    }

    /**
     * Sends an async message to the user with the passed in session id.
     * @param request An Http Request
     * @param id The session Id of the user to send the message to
     * @param message The message to send
     */
    protected void sendAsyncMessage(HttpServletRequest request, String id, String message)
    {
        // Ensure only administrators can perform this operation
        if (isAnyPermissionGranted(administratorPermissions))
        {
            HttpSession session = getSessionById(request, id);
            addAsyncMessages(session, message);
        }
    }

    /**
     * Broadcasts an async message to all users.
     * @param request An Http Request
     * @param message The message to send to all users
     */
    protected void broadcastAsyncMessage(HttpServletRequest request, String message)
    {
        // Ensure only administrators can perform this operation
        if (isAnyPermissionGranted(administratorPermissions))
        {
            // Get the open list of sessions
            Hashtable sessionTable = getSessions(request);

            // Iterate through the sessions
            for (Iterator iterator = sessionTable.values().iterator(); iterator.hasNext();)
            {
                // Get a session
                HttpSession session = (HttpSession)iterator.next();

                // Send message to the session
                addAsyncMessages(session, message);
            }
        }
    }

    /**
     * Returns the currently logged in user's session Id.
     *
     * @param request The HttpServletRequest
     * @return The session Id
     */
    protected String getCurrentSessionId(HttpServletRequest request)
    {
        return request.getSession().getId();
    }

    /**
     * Returns whether the passed in session Id is the current logged in user's sessionId.
     * @param id The session id to check
     * @param request The HttpServletRequest
     * @return True if the session Id is the currently logged in user's or false if not.
     */
    protected boolean isCurrentSession(String id, HttpServletRequest request)
    {
        return id.equals(getCurrentSessionId(request));
    }

    /**
     * Gets a list of HttpSession objects in a hash table.
     *
     * @param request The HttpServletRequest
     * @return The list of sessions
     */
    protected Hashtable getSessions(HttpServletRequest request)
    {
        // Get the servlet context
        WebAppServletContext webContext = (WebAppServletContext)request.getSession().getServletContext();

        // Get the session context
        SessionContext sessionContext = webContext.getSessionContext();

        // Return the list of sessions
        return sessionContext.getOpenSessions();
    }

    /**
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     */
    public void afterPropertiesSet() throws Exception
    {
    }
}
