/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License.
 *
 */
package org.apache.asyncweb.server.session;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.asyncweb.server.HttpSession;
import org.apache.asyncweb.server.util.LinkedPermitIssuer;
import org.apache.asyncweb.server.util.TimedPermit;
import org.apache.asyncweb.server.util.PermitExpirationListener;
import org.apache.asyncweb.server.util.TimedPermitIssuer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * A simple <code>SessionStore</code> implementation which holds all session
 * data in memory. A <code>TimedPermitIssuer</code> is employed to issue a time-out
 * permit for each issued session.
 *
 * @author irvingd
 *
 */
public class BasicSessionStore implements HttpSessionStore {

    private static final Logger LOG = LoggerFactory
            .getLogger(BasicSessionStore.class);

    /**
     * Default session timeout of 15 minutes
     */
    private static final long DEFAULT_SESSION_TIMEOUT = 900000;

    private Map<String, HttpSession> sessionMap = Collections
            .synchronizedMap(new HashMap<String, HttpSession>());

    private List<HttpSessionListener> listeners = Collections
            .synchronizedList(new ArrayList<HttpSessionListener>());

    private TimedPermitIssuer permitIssuer;

    private boolean isClosed;

    /**
     * Constructs with the default session timeout
     */
    public BasicSessionStore() {
        this(DEFAULT_SESSION_TIMEOUT);
    }

    /**
     * Constructs with a specified session timeout
     *
     * @param sessionTimeout  The session timeout (in ms)
     */
    public BasicSessionStore(long sessionTimeout) {
        permitIssuer = new LinkedPermitIssuer(sessionTimeout);
        permitIssuer.addPermitExpirationListener(new TimeoutListener());
        LOG.info("BasicSessionStore timeout: " + sessionTimeout + "ms");
    }

    /**
     * Adds a listener to this store
     *
     * @param listener The listener to add
     */
    public void addSessionListener(HttpSessionListener listener) {
        listeners.add(listener);
    }

    /**
     * Sets the listeners employed by this store.
     * Any existing listeners are removed
     *
     * @param listeners  The listeners to be added
     */
    public void setSessionListeners(Collection<HttpSessionListener> listeners) {
        synchronized (this.listeners) {
            this.listeners.clear();
            this.listeners.addAll(listeners);
        }
    }

    /**
     * Closes this store.
     * Our permit issuer is closed, and all sessions are destroyed.
     */
    public void close() {
        List<HttpSession> closureList = null;

        synchronized (sessionMap) {
            if (isClosed) {
                LOG.debug("Already closed");
                return;
            }
            LOG.debug("BasicSessionStore closing");
            permitIssuer.close();
            isClosed = true;
            closureList = new ArrayList<HttpSession>(sessionMap.values());
        }
        for ( HttpSession httpSession : closureList) {
         BasicSession session = (BasicSession) httpSession;
         LOG.debug("Closure: Destroying session: " + session.getId());
         session.destroy();
      }
    }

    /**
     * Creates a new session for the specified key.
     *
     * @param key  The session key
     * @return The created session, or <code>null</code> if a session is already
     *         held for the specified key
     */
    public HttpSession createSession(String key) {
        BasicSession created = null;
        synchronized (sessionMap) {
            if (isClosed) {
                throw new IllegalStateException("Store closed");
            }
            if (!sessionMap.containsKey(key)) {
                created = new BasicSession(key, this);
                sessionMap.put(key, created);
                TimedPermit permit = permitIssuer.issuePermit(created);
                created.setPermit(permit);
            }
        }
        if (created != null) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("New session created with key '" + key
                        + "'. Firing notifications");
            }
            fireCreated(created);
        }
        return created;
    }

    /**
     * Locates the session with the specified key.
     * If the session is found, we request it to renew its access permit.
     *
     * @param key  The key for which a session is required
     * @return     The located session, or <code>null</code> if no session with the
     *             specified key was found
     */
    public HttpSession locateSession(String key) {
        BasicSession session = (BasicSession) sessionMap.get(key);
        if (session != null) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Located session with key '" + key
                        + "'. Marking as accessed");
            }
            session.access();
        }
        return session;
    }

    /**
     * Invoked by a session we created when it successfully processes an expiry.
     * The session is removed from our session map, and expiry notifications are fired.
     *
     * @param session  The expired session
     */
    void sessionExpired(BasicSession session) {
        if (LOG.isDebugEnabled()) {
            LOG
                    .debug("Session has been expired. Processing notifications for '"
                            + session.getId() + "'");
        }
        sessionMap.remove(session.getId());
        fireExpiry(session);
    }

    /**
     * Invoked by a session we created when it successfully processes a destruction
     * request.
     * The session is removed from our session map, and destruction notifications
     * are fired
     *
     * @param session  The destroyed session
     */
    void sessionDestroyed(BasicSession session) {
        if (LOG.isDebugEnabled()) {
            LOG
                    .debug("Session has been destroyed. Processing notifications for '"
                            + session.getId() + "'");
        }
        sessionMap.remove(session.getId());
        fireDestroyed(session);
    }

    /**
     * Invoked when the permit associated with the specified session expires.
     * We simply request the session to expire itself.
     * If the session is not already destroyed, it will request us to fire
     * notifications on its behalf.
     *
     * @param session  The expired session
     */
    private void sessionPermitExpired(BasicSession session) {
        session.expire();
    }

    /**
     * Fires creation notification to all listeners assocaited with this store
     *
     * @param session  The expired session
     */
    private void fireCreated(HttpSession session) {
        synchronized (listeners) {
            for (HttpSessionListener listener : listeners) {
            listener.sessionCreated(session);
         }
        }
    }

    /**
     * Fires destruction notification to all listeners assocaited with this store
     *
     * @param session  The expired session
     */
    private void fireDestroyed(HttpSession session) {
        synchronized (listeners) {
            for (HttpSessionListener listener : listeners) {
            listener.sessionDestroyed(session);
         }
        }
    }

    /**
     * Fires expiry notification to all listeners assocaited with this store
     *
     * @param session  The expired session
     */
    private void fireExpiry(HttpSession session) {
        synchronized (listeners) {
            for (HttpSessionListener listener : listeners) {
            listener.sessionExpired(session);
         }
        }
    }

    /**
     * Receives notifications of timed out permits issued by this store,
     * and triggers expiry of the associated session
     *
     * @author irvingd
     *
     */
    private class TimeoutListener implements PermitExpirationListener
    {

        /**
         * Invoked when a permit issued for a session expires
         *
         * @param session  The session which has expired
         */
        public void permitExpired(Object session) {
            sessionPermitExpired((BasicSession) session);
        }

    }

}
