//
//  ========================================================================
//  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.gcloud.memcached.session;


import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.util.Map;

import org.eclipse.jetty.gcloud.session.GCloudSessionManager;
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;

import com.google.cloud.datastore.Key;

import net.rubyeye.xmemcached.MemcachedClient;
import net.rubyeye.xmemcached.XMemcachedClient;
import net.rubyeye.xmemcached.XMemcachedClientBuilder;
import net.rubyeye.xmemcached.transcoders.SerializingTranscoder;

/**
 * GCloudMemcachedSessionManager
 *
 * Use memcached in front of GCloudDataStore
 *
 */
public class GCloudMemcachedSessionManager extends GCloudSessionManager
{
    private  final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
    
    protected String _host;
    protected String _port;
    protected MemcachedClient _client;
    protected int _expirySec = 0;
    private boolean _heartbeats = true;

    

    /**
     * ContextClassloaderSerializingTranscoder
     *
     * A xmemcached transcoder that will use the thread context classloader to
     * resolve classes during object deserialization: necessary for Servlet Spec
     * classloading order of context classloader first.
     *  
     */
    public class ContextClassloaderSerializingTranscoder extends SerializingTranscoder
    {

        @Override
        protected Object deserialize(byte[] in)
        {

            if (in == null)
                return null;

            Object rv = null;
            try (ByteArrayInputStream bis = new ByteArrayInputStream(in);ObjectInputStream is = new ClassLoadingObjectInputStream(bis);)
            {

                rv = is.readObject();
            }
            catch (IOException e)
            {
                LOG.warn("Caught IOException decoding " + in.length + " bytes of data", e);
            }
            catch (ClassNotFoundException e)
            {
                LOG.warn("Caught CNFE decoding " + in.length + " bytes of data", e);
            }
            
            return rv;

        }
    }

    
    
    /**
     * MemcacheSession
     *
     * Needed to make a constructor public.
     */
    public class MemcacheSession extends GCloudSessionManager.Session
    {

        public MemcacheSession(String sessionId, long created, long accessed, long maxInterval)
        {
            super(sessionId, created, accessed, maxInterval);
        }  
    }
    
    /**
     * Every time a Session is put into the cache one of these objects
     * is created to copy the data out of the in-memory session, and 
     * every time an object is read from the cache one of these objects
     * a fresh Session object is created based on the data held by this
     * object.
     */
    public class SerializableSessionData implements Serializable
    {
        /**
         * 
         */
        private static final long serialVersionUID = -7779120106058533486L;
        String clusterId;
        String contextPath;
        String vhost;
        long accessed;
        long lastAccessed;
        long createTime;
        long cookieSetTime;
        String lastNode;
        long expiry;
        long maxInactive;
        Map<String, Object> attributes;



        public SerializableSessionData()
        {}


        public SerializableSessionData(Session s)
        {
            clusterId = s.getClusterId();
            contextPath = s.getContextPath();
            vhost = s.getVHost();
            accessed = s.getAccessed();
            lastAccessed = s.getLastAccessedTime();
            createTime = s.getCreationTime();
            cookieSetTime = s.getCookieSetTime();
            lastNode = s.getLastNode();
            expiry = s.getExpiry();
            maxInactive = s.getMaxInactiveInterval();
            attributes = s.getAttributeMap();
       }
       
        
        private void writeObject(java.io.ObjectOutputStream out) throws IOException
        { 
            out.writeUTF(clusterId); //session id
            out.writeUTF(contextPath); //context path
            out.writeUTF(vhost); //first vhost

            out.writeLong(accessed);//accessTime
            out.writeLong(lastAccessed); //lastAccessTime
            out.writeLong(createTime); //time created
            out.writeLong(cookieSetTime);//time cookie was set
            out.writeUTF(lastNode); //name of last node managing

            out.writeLong(expiry); 
            out.writeLong(maxInactive);
            out.writeObject(attributes);
        }

        private void readObject(java.io.ObjectInputStream ois) throws IOException, ClassNotFoundException
        {
            clusterId = ois.readUTF();
            contextPath = ois.readUTF();
            vhost = ois.readUTF();
            accessed = ois.readLong();//accessTime
            lastAccessed = ois.readLong(); //lastAccessTime
            createTime = ois.readLong(); //time created
            cookieSetTime = ois.readLong();//time cookie was set
            lastNode = ois.readUTF(); //last managing node
            expiry = ois.readLong(); 
            maxInactive = ois.readLong();
            Object o = ois.readObject();
            attributes = ((Map<String,Object>)o);
        }
    }


    
    
    
    
    /**
     * @return the expiry setting for memcached
     */
    public int getExpirySec()
    {
        return _expirySec;
    }

    /**
     * @param expirySec the time in seconds for an item to remain in memcached
     */
    public void setExpirySec(int expirySec)
    {
        _expirySec = expirySec;
    }
    
    
    /**
     * @param heartbeats if true memcached heartbeats are enabled. Default is true.
     */
    public void setHeartbeats (boolean heartbeats)
    {
        _heartbeats  = heartbeats;
    }

    
    @Override
    public void doStart() throws Exception
    {
        if (StringUtil.isBlank(_host) || StringUtil.isBlank(_port))
            throw new IllegalStateException("Memcached host and/or port not configured");

        LOG.info("Memcached host {} port {}", _host, _port);
        
        XMemcachedClientBuilder builder = new XMemcachedClientBuilder(_host+":"+_port);
        _client = builder.build();
        _client.setEnableHeartBeat(_heartbeats);
        

        _client.setTranscoder(new ContextClassloaderSerializingTranscoder());
        super.doStart();
    }

    @Override
    public void doStop() throws Exception
    {
        super.doStop();
        _client.shutdown();
        _client = null;
    }

    @Override
    protected Session load(Key key) throws Exception
    {
        //first try the memcache cache
        if (LOG.isDebugEnabled()) LOG.debug("Loading key {} from memcached ", key.name());
        Session session =  loadFromMemcached(key.name());
        if (session != null)
            return session;

        //then try gcloudatastore
        return super.load(key);
    }

    /**
     * @param key the key for the memcache item
     * @return the Session inflated from memcache
     * @throws Exception
     */
    protected Session loadFromMemcached(String key) throws Exception
    {
        SerializableSessionData sd = _client.get(key);

        if (sd == null)
            return null;

        Session session = new MemcacheSession (sd.clusterId, sd.createTime, sd.accessed, sd.maxInactive);
        session.setLastNode(sd.lastNode);
        session.setContextPath(sd.contextPath);
        session.setVHost(sd.vhost);
        session.setCookieSetTime(sd.cookieSetTime);
        session.setLastAccessedTime(sd.lastAccessed);
        session.setLastNode(sd.lastNode);
        session.setExpiry(sd.expiry);
        session.addAttributes(sd.attributes);
        return session;
    }


    @Override
    protected void save(Session session) throws Exception
    {
        //save to gcloud and then memcache
        super.save(session);        
        saveToMemcached(session);
    }

    
    
    @Override
    protected void delete (GCloudSessionManager.Session session)
    {  
        Exception memcacheException = null;
        try
        {
            deleteFromMemcached(session);
        }
        catch (Exception e)
        {
            memcacheException = e;
        }
        
        super.delete(session);
        if (memcacheException != null)
            throw new RuntimeException(memcacheException);
    }

    
    protected void deleteFromMemcached(Session session) throws Exception
    {
        Key gcloudKey = makeKey(session, _context);
        _client.delete(gcloudKey.name());
    }

    /**
     * Store the session into memcached
     * @param session the Session to be serialized
     * @throws Exception
     */
    protected void saveToMemcached(Session session) throws Exception
    {
        Key gcloudKey = makeKey(session, _context);
        _client.set(gcloudKey.name(), getExpirySec(), new SerializableSessionData(session));
    }

    /**
     * @return the host address of the memcached server
     */
    public String getHost()
    {
        return _host;
    }

    /**
     * @param host the host address of the memcached server
     */
    public void setHost(String host)
    {
        _host = host;
    }

    /**
     * @return the port of the memcached server
     */
    public String getPort()
    {
        return _port;
    }
    
   

    /**
     * @param port the port of the memcached server
     */
    public void setPort(String port)
    {
        _port = port;
    }
}
