//
//  ========================================================================
//  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.nosql.mongodb;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.server.session.AbstractSessionExpiryTest;
import org.eclipse.jetty.server.session.AbstractTestServer;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.StringUtil;
import org.junit.Test;

import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;


public class SessionExpiryTest extends AbstractSessionExpiryTest
{

    @Override
    public AbstractTestServer createServer(int port, int max, int scavenge)
    {
       return new MongoTestServer(port,max,scavenge);
    }

    @Test
    public void testSessionNotExpired() throws Exception
    {
        super.testSessionNotExpired();
    }
    
    @Test
    public void testSessionExpiry() throws Exception
    {
        super.testSessionExpiry();
    }
    
    @Test
    public void testBigSessionExpiry() throws Exception
    {
        String contextPath = "";
        String servletMapping = "/server";
        int inactivePeriod = Integer.MAX_VALUE * 60; //integer overflow
        int scavengePeriod = 1;
        AbstractTestServer server1 = createServer(0, inactivePeriod, scavengePeriod);
        ChangeTimeoutServlet servlet = new ChangeTimeoutServlet();
        ServletHolder holder = new ServletHolder(servlet);
        ServletContextHandler context = server1.addContext(contextPath);
        context.addServlet(holder, servletMapping);
        TestHttpSessionListener listener = new TestHttpSessionListener();
        
        context.getSessionHandler().addEventListener(listener);
        
        server1.start();
        int port1 = server1.getPort();

        try
        {
            HttpClient client = new HttpClient();
            client.start();
            String url = "http://localhost:" + port1 + contextPath + servletMapping;

            //make a request to set up a session on the server
            ContentResponse response1 = client.GET(url + "?action=init");
            assertEquals(HttpServletResponse.SC_OK,response1.getStatus());
            String sessionCookie = response1.getHeaders().get("Set-Cookie");
            assertTrue(sessionCookie != null);
            // Mangle the cookie, replacing Path with $Path, etc.
            sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
            
            String sessionId = AbstractTestServer.extractSessionId(sessionCookie);     
            
            DBCollection sessions = ((MongoSessionIdManager)((MongoTestServer)server1).getServer().getSessionIdManager()).getSessions();
            verifySessionCreated(listener,sessionId);
            //verify that the session timeout is set in mongo
            verifySessionTimeout(sessions, sessionId, inactivePeriod);
            
            //get the session expiry time from mongo
            long expiry = getSessionExpiry(sessions, sessionId);
            assertEquals(0, expiry);

        }
        finally
        {
            server1.stop();
        } 
    }
    
    @Test
    public void changeSessionTimeout() throws Exception
    {
        String contextPath = "";
        String servletMapping = "/server";
        int inactivePeriod = 10;
        int scavengePeriod = 1;
        AbstractTestServer server1 = createServer(0, inactivePeriod, scavengePeriod);
        ChangeTimeoutServlet servlet = new ChangeTimeoutServlet();
        ServletHolder holder = new ServletHolder(servlet);
        ServletContextHandler context = server1.addContext(contextPath);
        context.addServlet(holder, servletMapping);
        TestHttpSessionListener listener = new TestHttpSessionListener();
        
        context.getSessionHandler().addEventListener(listener);
        
        server1.start();
        int port1 = server1.getPort();

        try
        {
            HttpClient client = new HttpClient();
            client.start();
            String url = "http://localhost:" + port1 + contextPath + servletMapping;

            //make a request to set up a session on the server
            ContentResponse response1 = client.GET(url + "?action=init");
            assertEquals(HttpServletResponse.SC_OK,response1.getStatus());
            String sessionCookie = response1.getHeaders().get("Set-Cookie");
            assertTrue(sessionCookie != null);
            // Mangle the cookie, replacing Path with $Path, etc.
            sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
            
            String sessionId = AbstractTestServer.extractSessionId(sessionCookie);     
            
            DBCollection sessions = ((MongoSessionIdManager)((MongoTestServer)server1).getServer().getSessionIdManager()).getSessions();
            verifySessionCreated(listener,sessionId);
            //verify that the session timeout is set in mongo
            verifySessionTimeout(sessions, sessionId, inactivePeriod);
            
            //get the session expiry time from mongo
            long expiry = getSessionExpiry(sessions, sessionId);
           
            //make another request to change the session timeout to a smaller value
            inactivePeriod = 5;
            Request request = client.newRequest(url + "?action=change&val="+inactivePeriod);
            request.getHeaders().add("Cookie", sessionCookie);
            ContentResponse response2 = request.send();
            assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
 
            
            //check the timeout in mongo
            verifySessionTimeout(sessions, sessionId, inactivePeriod);
            //check the session expiry time has decreased from previous value
            assertTrue(getSessionExpiry(sessions, sessionId)<expiry);
            expiry = getSessionExpiry(sessions, sessionId);
            
            //increase the session timeout
            inactivePeriod = 20;
            request = client.newRequest(url + "?action=change&val="+inactivePeriod);
            request.getHeaders().add("Cookie", sessionCookie);
            response2 = request.send();
            assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
            //verify that the session timeout is set in mongo
            verifySessionTimeout(sessions, sessionId, inactivePeriod);
            assertTrue(getSessionAccessed(sessions, sessionId)+ (1000L*inactivePeriod) == getSessionExpiry(sessions, sessionId));            
        }
        finally
        {
            server1.stop();
        }     
    }
    
    
    @Test
    public void testChangeNewSessionTimeout () throws Exception
    {
        String contextPath = "";
        String servletMapping = "/server";
        int inactivePeriod = 10;
        int scavengePeriod = 1;
        AbstractTestServer server1 = createServer(0, inactivePeriod, scavengePeriod);
        ImmediateChangeTimeoutServlet servlet = new ImmediateChangeTimeoutServlet();
        ServletHolder holder = new ServletHolder(servlet);
        ServletContextHandler context = server1.addContext(contextPath);
        context.addServlet(holder, servletMapping);
        TestHttpSessionListener listener = new TestHttpSessionListener();
        
        context.getSessionHandler().addEventListener(listener);
        
        server1.start();
        int port1 = server1.getPort();

        try
        {
            HttpClient client = new HttpClient();
            client.start();
            String url = "http://localhost:" + port1 + contextPath + servletMapping;

            inactivePeriod = 5; //change from the sessionmanager configured default
            
            //make a request to set up a session on the server and change its inactive setting straight away
            ContentResponse response1 = client.GET(url + "?action=init&val="+inactivePeriod);
            assertEquals(HttpServletResponse.SC_OK,response1.getStatus());
            String sessionCookie = response1.getHeaders().get("Set-Cookie");
            assertTrue(sessionCookie != null);
            // Mangle the cookie, replacing Path with $Path, etc.
            sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
            
            String sessionId = AbstractTestServer.extractSessionId(sessionCookie);     
            
            DBCollection sessions = ((MongoSessionIdManager)((MongoTestServer)server1).getServer().getSessionIdManager()).getSessions();
            verifySessionCreated(listener,sessionId);
            //verify that the session timeout is the new value and not the default
            verifySessionTimeout(sessions, sessionId, inactivePeriod);             
        }
        finally
        {
            server1.stop();
        }     
    }
    
    @Test
    public void testRequestForSessionWithChangedTimeout () throws Exception
    {
      String contextPath = "";
      String servletMapping = "/server";
      int inactivePeriod = 5;
      int scavengePeriod = 1;
      AbstractTestServer server1 = createServer(0, inactivePeriod, scavengePeriod);
      ChangeTimeoutServlet servlet = new ChangeTimeoutServlet();
      ServletHolder holder = new ServletHolder(servlet);
      ServletContextHandler context = server1.addContext(contextPath);
      context.addServlet(holder, servletMapping);
      TestHttpSessionListener listener = new TestHttpSessionListener();
      
      context.getSessionHandler().addEventListener(listener);
      
      server1.start();
      int port1 = server1.getPort();

      try
      {
          HttpClient client = new HttpClient();
          client.start();
          String url = "http://localhost:" + port1 + contextPath + servletMapping;

          //make a request to set up a session on the server with the session manager's inactive timeout
          ContentResponse response = client.GET(url + "?action=init");
          assertEquals(HttpServletResponse.SC_OK,response.getStatus());
          String sessionCookie = response.getHeaders().get("Set-Cookie");
          assertTrue(sessionCookie != null);
          // Mangle the cookie, replacing Path with $Path, etc.
          sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
             
         
          //make another request to change the session timeout to a larger value
          int newInactivePeriod = 100;
          Request request = client.newRequest(url + "?action=change&val="+newInactivePeriod);
          request.getHeaders().add("Cookie", sessionCookie);
          response = request.send();
          assertEquals(HttpServletResponse.SC_OK,response.getStatus());
          
          //stop and restart the session manager to ensure it needs to reload the session
          context.stop();
          context.start();

          //wait until the session manager timeout has passed and re-request the session
          //which should still be valid
          Thread.currentThread().sleep(inactivePeriod*1000L);

          request = client.newRequest(url + "?action=check");
          request.getHeaders().add("Cookie", sessionCookie);
          response = request.send();
          assertEquals(HttpServletResponse.SC_OK,response.getStatus());
          String sessionCookie2 = response.getHeaders().get("Set-Cookie");
          assertNull(sessionCookie2);
          
      }
      finally
      {
          server1.stop();
      }     
    }
    
    
    public void verifySessionTimeout (DBCollection sessions, String id, int sec) throws Exception
    {
        assertNotNull(sessions);
        assertNotNull(id);
        
        DBObject o = sessions.findOne(new BasicDBObject(MongoSessionManager.__ID,id));
        assertNotNull(o);
        Integer maxIdle = (Integer)o.get(MongoSessionManager.__MAX_IDLE);
        assertNotNull(maxIdle);
        assertEquals(sec, maxIdle.intValue());
    }
    
    public long getSessionExpiry (DBCollection sessions, String id) throws Exception
    {
        assertNotNull(sessions);
        assertNotNull(id);
        
        DBObject o = sessions.findOne(new BasicDBObject(MongoSessionManager.__ID,id));
        assertNotNull(o);
        Long expiry = (Long)o.get(MongoSessionManager.__EXPIRY);
        return (expiry == null? null : expiry.longValue());
    }
    
    public int getSessionMaxInactiveInterval (DBCollection sessions, String id) throws Exception
    {
        assertNotNull(sessions);
        assertNotNull(id);
        
        DBObject o = sessions.findOne(new BasicDBObject(MongoSessionManager.__ID,id));
        assertNotNull(o);
        Integer inactiveInterval = (Integer)o.get(MongoSessionManager.__MAX_IDLE);
        return (inactiveInterval == null? null : inactiveInterval.intValue());
    }
    
    public long getSessionAccessed (DBCollection sessions, String id) throws Exception
    {
        assertNotNull(sessions);
        assertNotNull(id);
        
        DBObject o = sessions.findOne(new BasicDBObject(MongoSessionManager.__ID,id));
        assertNotNull(o);
        Long accessed = (Long)o.get(MongoSessionManager.__ACCESSED);
        return (accessed == null? null : accessed.longValue());
    }
    
    public void debugPrint (DBCollection sessions, String id) throws Exception
    {
        assertNotNull(sessions);
        assertNotNull(id);
        
        DBObject o = sessions.findOne(new BasicDBObject(MongoSessionManager.__ID,id));
        assertNotNull(o);
        System.err.println(o);
    }
    
    public static class ChangeTimeoutServlet extends HttpServlet
    {

        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException
        {
            String action = request.getParameter("action");
            if ("init".equals(action))
            {
                HttpSession session = request.getSession(true);
                session.setAttribute("test", "test");
            }
            else if ("change".equals(action))
            {
                String tmp = request.getParameter("val");
                int val = (StringUtil.isBlank(tmp)?0:Integer.valueOf(tmp.trim()));
                HttpSession session = request.getSession(false);
                assertNotNull(session);
                session.setMaxInactiveInterval(val);
            }
            else if ("check".equals(action))
            {
                HttpSession session = request.getSession(false);
                assertNotNull(session);
            }
        }
    }
    
    public static class ImmediateChangeTimeoutServlet extends HttpServlet
    {

        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException
        {
            String action = request.getParameter("action");
            if ("init".equals(action))
            {
                HttpSession session = request.getSession(true);
                assertNotNull(session);
                String tmp = request.getParameter("val");
                int val = (StringUtil.isBlank(tmp)?0:Integer.valueOf(tmp.trim()));
                session.setMaxInactiveInterval(val);
            }
            else if ("change".equals(action))
            {
                String tmp = request.getParameter("val");
                int val = (StringUtil.isBlank(tmp)?0:Integer.valueOf(tmp.trim()));
                HttpSession session = request.getSession(false);
                assertNotNull(session);
                session.setMaxInactiveInterval(val);
            }
        }
    }

}
