//
//  ========================================================================
//  Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
//  ------------------------------------------------------------------------
//  All rights reserved. This program and the accompanying materials
//  are made available under the terms of the Eclipse Public License v1.0
//  and Apache License v2.0 which accompanies this distribution.
//
//      The Eclipse Public License is available at
//      http://www.eclipse.org/legal/epl-v10.html
//
//      The Apache License v2.0 is available at
//      http://www.opensource.org/licenses/apache2.0.php
//
//  You may elect to redistribute this code under either of these licenses.
//  ========================================================================
//

package org.eclipse.jetty.server.session;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionContext;
import javax.servlet.http.HttpSessionEvent;

import org.eclipse.jetty.server.SessionManager;
import org.eclipse.jetty.util.log.Logger;

/**
 *
 * <p>
 * Implements {@link javax.servlet.http.HttpSession} from the <code>javax.servlet</code> package.
 * </p>
 *
 */
@SuppressWarnings("deprecation")
public abstract class AbstractSession implements AbstractSessionManager.SessionIf
{
    final static Logger LOG = SessionHandler.LOG;
    public final static String SESSION_KNOWN_ONLY_TO_AUTHENTICATED="org.eclipse.jetty.security.sessionKnownOnlytoAuthenticated";
    private  String _clusterId; // ID without any node (ie "worker") id appended
    private  String _nodeId;    // ID of session with node(ie "worker") id appended
    private final AbstractSessionManager _manager;
    private boolean _idChanged;
    private final long _created;
    private long _cookieSet;
    private long _accessed;         // the time of the last access
    private long _lastAccessed;     // the time of the last access excluding this one
    private boolean _invalid;
    private boolean _doInvalidate;
    private long _maxIdleMs;
    private boolean _newSession;
    private int _requests;



    /* ------------------------------------------------------------- */
    protected AbstractSession(AbstractSessionManager abstractSessionManager, HttpServletRequest request)
    {
        _manager = abstractSessionManager;

        _newSession=true;
        _created=System.currentTimeMillis();
        _clusterId=_manager._sessionIdManager.newSessionId(request,_created);
        _nodeId=_manager._sessionIdManager.getNodeId(_clusterId,request);
        _accessed=_created;
        _lastAccessed=_created;
        _requests=1;
        _maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1;
        if (LOG.isDebugEnabled())
            LOG.debug("new session & id "+_nodeId+" "+_clusterId);
    }

    /* ------------------------------------------------------------- */
    protected AbstractSession(AbstractSessionManager abstractSessionManager, long created, long accessed, String clusterId)
    {
        _manager = abstractSessionManager;
        _created=created;
        _clusterId=clusterId;
        _nodeId=_manager._sessionIdManager.getNodeId(_clusterId,null);
        _accessed=accessed;
        _lastAccessed=accessed;
        _requests=1;
        _maxIdleMs=_manager._dftMaxIdleSecs>0?_manager._dftMaxIdleSecs*1000L:-1;
        if (LOG.isDebugEnabled())
            LOG.debug("new session "+_nodeId+" "+_clusterId);
    }

    /* ------------------------------------------------------------- */
    /**
     * asserts that the session is valid
     */
    protected void checkValid() throws IllegalStateException
    {
        if (_invalid)
            throw new IllegalStateException();
    }
    
    /* ------------------------------------------------------------- */
    /** Check to see if session has expired as at the time given.
     * @param time
     * @return
     */
    protected boolean checkExpiry(long time)
    {
        if (_maxIdleMs>0 && _lastAccessed>0 && _lastAccessed + _maxIdleMs < time)
            return true;
        return false;
    }

    /* ------------------------------------------------------------- */
    @Override
    public AbstractSession getSession()
    {
        return this;
    }

    /* ------------------------------------------------------------- */
    public long getAccessed()
    {
        synchronized (this)
        {
            return _accessed;
        }
    }

    /* ------------------------------------------------------------- */
    public abstract Map<String,Object> getAttributeMap();


 
    

    /* ------------------------------------------------------------ */
    public abstract int getAttributes();
  

 

    /* ------------------------------------------------------------ */
    public abstract Set<String> getNames();
  

    /* ------------------------------------------------------------- */
    public long getCookieSetTime()
    {
        return _cookieSet;
    }

    /* ------------------------------------------------------------- */
    @Override
    public long getCreationTime() throws IllegalStateException
    {
        checkValid();
        return _created;
    }

    /* ------------------------------------------------------------ */
    @Override
    public String getId() throws IllegalStateException
    {
        return _manager._nodeIdInSessionId?_nodeId:_clusterId;
    }

    /* ------------------------------------------------------------- */
    public String getNodeId()
    {
        return _nodeId;
    }

    /* ------------------------------------------------------------- */
    public String getClusterId()
    {
        return _clusterId;
    }

    /* ------------------------------------------------------------- */
    @Override
    public long getLastAccessedTime() throws IllegalStateException
    {
        checkValid();
        return _lastAccessed;
    }
    
    /* ------------------------------------------------------------- */
    public void setLastAccessedTime(long time)
    {
        _lastAccessed = time;
    }

    /* ------------------------------------------------------------- */
    @Override
    public int getMaxInactiveInterval()
    {
        return (int)(_maxIdleMs/1000);
    }

    /* ------------------------------------------------------------ */
    /*
     * @see javax.servlet.http.HttpSession#getServletContext()
     */
    @Override
    public ServletContext getServletContext()
    {
        return _manager._context;
    }

    /* ------------------------------------------------------------- */
    @Deprecated
    @Override
    public HttpSessionContext getSessionContext() throws IllegalStateException
    {
        checkValid();
        return AbstractSessionManager.__nullSessionContext;
    }

    /* ------------------------------------------------------------- */
    /**
     * @deprecated As of Version 2.2, this method is replaced by
     *             {@link #getAttribute}
     */
    @Deprecated
    @Override
    public Object getValue(String name) throws IllegalStateException
    {
        return getAttribute(name);
    }

 

    /* ------------------------------------------------------------ */
    public void renewId(HttpServletRequest request)
    {
        _manager._sessionIdManager.renewSessionId(getClusterId(), getNodeId(), request); 
        setIdChanged(true);
    }
       
    /* ------------------------------------------------------------- */
    public SessionManager getSessionManager()
    {
        return _manager;
    }

    /* ------------------------------------------------------------ */
    protected void setClusterId (String clusterId)
    {
        _clusterId = clusterId;
    }
    
    /* ------------------------------------------------------------ */
    protected void setNodeId (String nodeId)
    {
        _nodeId = nodeId;
    }
    

    /* ------------------------------------------------------------ */
    protected boolean access(long time)
    {
        synchronized(this)
        {
            if (_invalid)
                return false;
            _newSession=false;
            _lastAccessed=_accessed;
            _accessed=time;

            if (checkExpiry(time))
            {
                invalidate();
                return false;
            }
            _requests++;
            return true;
        }
    }

    /* ------------------------------------------------------------ */
    protected void complete()
    {
        synchronized(this)
        {
            _requests--;
            if (_doInvalidate && _requests<=0  )
                doInvalidate();
        }
    }


    /* ------------------------------------------------------------- */
    protected void timeout() throws IllegalStateException
    {
        // remove session from context and invalidate other sessions with same ID.
        _manager.removeSession(this,true);

        // Notify listeners and unbind values
        boolean do_invalidate=false;
        synchronized (this)
        {
            if (!_invalid)
            {
                if (_requests<=0)
                    do_invalidate=true;
                else
                    _doInvalidate=true;
            }
        }
        if (do_invalidate)
            doInvalidate();
    }

    /* ------------------------------------------------------------- */
    @Override
    public void invalidate() throws IllegalStateException
    {
        checkValid();
        // remove session from context and invalidate other sessions with same ID.
        _manager.removeSession(this,true);
        doInvalidate();
    }

    /* ------------------------------------------------------------- */
    protected void doInvalidate() throws IllegalStateException
    {
        try
        {
            if (LOG.isDebugEnabled())
                LOG.debug("invalidate {}",_clusterId);
            if (isValid())
                clearAttributes();
        }
        finally
        {
            synchronized (this)
            {
                // mark as invalid
                _invalid=true;
            }
        }
    }

    /* ------------------------------------------------------------- */
    public abstract void clearAttributes();
   

    /* ------------------------------------------------------------- */
    public boolean isIdChanged()
    {
        return _idChanged;
    }

    /* ------------------------------------------------------------- */
    @Override
    public boolean isNew() throws IllegalStateException
    {
        checkValid();
        return _newSession;
    }

    /* ------------------------------------------------------------- */
    /**
     * @deprecated As of Version 2.2, this method is replaced by
     *             {@link #setAttribute}
     */
    @Deprecated
    @Override
    public void putValue(java.lang.String name, java.lang.Object value) throws IllegalStateException
    {
        changeAttribute(name,value);
    }

    /* ------------------------------------------------------------ */
    @Override
    public void removeAttribute(String name)
    {
        setAttribute(name,null);
    }

    /* ------------------------------------------------------------- */
    /**
     * @deprecated As of Version 2.2, this method is replaced by
     *             {@link #removeAttribute}
     */
    @Deprecated
    @Override
    public void removeValue(java.lang.String name) throws IllegalStateException
    {
        removeAttribute(name);
    }
    
    /* ------------------------------------------------------------ */
    @Override
    public Enumeration<String> getAttributeNames()
    {
        synchronized (this)
        {
            checkValid();
            return doGetAttributeNames();
        }
    }
    
    /* ------------------------------------------------------------- */
    /**
     * @deprecated As of Version 2.2, this method is replaced by
     *             {@link #getAttributeNames}
     */
    @Deprecated
    @Override
    public String[] getValueNames() throws IllegalStateException
    {
        synchronized(this)
        {
            checkValid();
            Enumeration<String> anames = doGetAttributeNames();
            if (anames == null)
                return new String[0];
            ArrayList<String> names = new ArrayList<String>();
            while (anames.hasMoreElements())
                names.add(anames.nextElement());
            return names.toArray(new String[names.size()]);
        }
    }
    

    /* ------------------------------------------------------------ */
    public abstract Object doPutOrRemove(String name, Object value);
 

    /* ------------------------------------------------------------ */
    public abstract Object doGet(String name);
    
    
    /* ------------------------------------------------------------ */
    public abstract Enumeration<String> doGetAttributeNames();
    
    
    /* ------------------------------------------------------------ */
    @Override
    public Object getAttribute(String name)
    {
        synchronized (this)
        {
            checkValid();
            return doGet(name);
        }
    }
   

    /* ------------------------------------------------------------ */
    @Override
    public void setAttribute(String name, Object value)
    {
        changeAttribute(name,value);
    }
    
    /* ------------------------------------------------------------ */
    /**
     * @param name
     * @param value
     * @deprecated use changeAttribute(String,Object) instead
     * @return
     */
    protected boolean updateAttribute (String name, Object value)
    {
        Object old=null;
        synchronized (this)
        {
            checkValid();
            old=doPutOrRemove(name,value);
        }

        if (value==null || !value.equals(old))
        {
            if (old!=null)
                unbindValue(name,old);
            if (value!=null)
                bindValue(name,value);

            _manager.doSessionAttributeListeners(this,name,old,value);
            return true;
        }
        return false;
    }
    
    
    /* ------------------------------------------------------------ */
    /**
     * Either set (perhaps replace) or remove the value of the attribute
     * in the session. The appropriate session attribute listeners are
     * also called.
     * 
     * @param name
     * @param value
     * @return
     */
    protected Object changeAttribute (String name, Object value)
    {
        Object old=null;
        synchronized (this)
        {
            checkValid();
            old=doPutOrRemove(name,value);
        }

        callSessionAttributeListeners(name, value, old);

        return old;
    }

    /* ------------------------------------------------------------ */
    /**
     * Call binding and attribute listeners based on the new and old
     * values of the attribute.
     * 
     * @param name name of the attribute
     * @param newValue  new value of the attribute
     * @param oldValue previous value of the attribute
     */
    protected void callSessionAttributeListeners (String name, Object newValue, Object oldValue)
    {
        if (newValue==null || !newValue.equals(oldValue))
        {
            if (oldValue!=null)
                unbindValue(name,oldValue);
            if (newValue!=null)
                bindValue(name,newValue);

            _manager.doSessionAttributeListeners(this,name,oldValue,newValue);
        }
    }
  

    /* ------------------------------------------------------------- */
    public void setIdChanged(boolean changed)
    {
        _idChanged=changed;
    }

    /* ------------------------------------------------------------- */
    @Override
    public void setMaxInactiveInterval(int secs)
    {
        _maxIdleMs=(long)secs*1000L;
    }

    /* ------------------------------------------------------------- */
    @Override
    public String toString()
    {
        return this.getClass().getName()+":"+getId()+"@"+hashCode();
    }

    /* ------------------------------------------------------------- */
    /** If value implements HttpSessionBindingListener, call valueBound() */
    public void bindValue(java.lang.String name, Object value)
    {
        if (value!=null&&value instanceof HttpSessionBindingListener)
            ((HttpSessionBindingListener)value).valueBound(new HttpSessionBindingEvent(this,name));
    }

    /* ------------------------------------------------------------ */
    public boolean isValid()
    {
        return !_invalid;
    }

    /* ------------------------------------------------------------- */
    protected void cookieSet()
    {
        synchronized (this)
        {
            _cookieSet=_accessed;
        }
    }

    /* ------------------------------------------------------------ */
    public int getRequests()
    {
        synchronized (this)
        {
            return _requests;
        }
    }

    /* ------------------------------------------------------------ */
    public void setRequests(int requests)
    {
        synchronized (this)
        {
            _requests=requests;
        }
    }

    /* ------------------------------------------------------------- */
    /** If value implements HttpSessionBindingListener, call valueUnbound() */
    public void unbindValue(java.lang.String name, Object value)
    {
        if (value!=null&&value instanceof HttpSessionBindingListener)
            ((HttpSessionBindingListener)value).valueUnbound(new HttpSessionBindingEvent(this,name));
    }

    /* ------------------------------------------------------------- */
    public void willPassivate()
    {
        synchronized(this)
        {
            HttpSessionEvent event = new HttpSessionEvent(this);
            for (Iterator<Object> iter = getAttributeMap().values().iterator(); iter.hasNext();)
            {
                Object value = iter.next();
                if (value instanceof HttpSessionActivationListener)
                {
                    HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
                    listener.sessionWillPassivate(event);
                }
            }
        }
    }

    /* ------------------------------------------------------------- */
    public void didActivate()
    {
        synchronized(this)
        {
            HttpSessionEvent event = new HttpSessionEvent(this);
            for (Iterator<Object> iter = getAttributeMap().values().iterator(); iter.hasNext();)
            {
                Object value = iter.next();
                if (value instanceof HttpSessionActivationListener)
                {
                    HttpSessionActivationListener listener = (HttpSessionActivationListener) value;
                    listener.sessionDidActivate(event);
                }
            }
        }
    }


}
