//
//  ========================================================================
//  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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.io.Serializable;

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 javax.servlet.http.HttpSessionActivationListener;
import javax.servlet.http.HttpSessionBindingEvent;
import javax.servlet.http.HttpSessionBindingListener;
import javax.servlet.http.HttpSessionEvent;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.junit.Test;


/**
 * DirtyAttributeTest
 *
 * Check that repeated calls to setAttribute with the same value do not cause writes to the
 * database - this is inferred via calls to passivate and activate  listeners.
 *
 *
 */
public class DirtyAttributeTest
{
    public static TestValue A_VALUE = new TestValue();
    public static TestValue B_VALUE = new TestValue();
    public static String THE_NAME = "__theName";
    public static int INACTIVE = 4;
    public static int SCAVENGE = 1;

    @Test
    public void testDirtyWrite() throws Exception
    {
        AbstractTestServer server = new JdbcTestServer(0,INACTIVE,SCAVENGE);
        
        ServletContextHandler ctxA = server.addContext("/mod");
        ctxA.addServlet(TestDirtyServlet.class, "/test");
        
        server.start();
        int port=server.getPort();
        try
        {
            HttpClient client = new HttpClient();
            client.start();
            try
            {
                // Perform a request to create a session              
                ContentResponse response = client.GET("http://localhost:" + port + "/mod/test?action=create");
                
                assertEquals(HttpServletResponse.SC_OK,response.getStatus());
                String sessionCookie = response.getHeaders().getStringField("Set-Cookie");
                assertTrue(sessionCookie != null);
                // Mangle the cookie, replacing Path with $Path, etc.
                sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
                
                //do another request to change the session attribute
                Request request = client.newRequest("http://localhost:" + port + "/mod/test?action=setA");
                request.header("Cookie", sessionCookie);
                response = request.send();

                assertEquals(HttpServletResponse.SC_OK,response.getStatus());
                A_VALUE.assertPassivatesEquals(1);
                A_VALUE.assertActivatesEquals(1);
                A_VALUE.assertBindsEquals(1);
                A_VALUE.assertUnbindsEquals(0);
                
                //do another request using the cookie to try changing the session attribute to the same value again              
                request= client.newRequest("http://localhost:" + port + "/mod/test?action=setA");
                request.header("Cookie", sessionCookie);
                response = request.send();
                assertEquals(HttpServletResponse.SC_OK,response.getStatus());
                A_VALUE.assertPassivatesEquals(2);
                A_VALUE.assertActivatesEquals(2);
                A_VALUE.assertBindsEquals(1);
                A_VALUE.assertUnbindsEquals(0);
                
                //do another request using the cookie and change to a different value             
                request= client.newRequest("http://localhost:" + port + "/mod/test?action=setB");
                request.header("Cookie", sessionCookie);
                response = request.send();
                assertEquals(HttpServletResponse.SC_OK,response.getStatus());
                B_VALUE.assertPassivatesEquals(1);
                B_VALUE.assertActivatesEquals(1);
                B_VALUE.assertBindsEquals(1);
                B_VALUE.assertUnbindsEquals(0);
                A_VALUE.assertBindsEquals(1);
                A_VALUE.assertUnbindsEquals(1);
                
            }
            finally
            {
                client.stop();
            }
        }
        finally
        {
            server.stop();
        }
    }
    
    public static class TestValue implements HttpSessionActivationListener, HttpSessionBindingListener, Serializable
    {
        int passivates = 0;
        int activates = 0;
        int binds = 0;
        int unbinds = 0;
        
        /** 
         * @see javax.servlet.http.HttpSessionActivationListener#sessionWillPassivate(javax.servlet.http.HttpSessionEvent)
         */
        public void sessionWillPassivate(HttpSessionEvent se)
        {
            ++passivates;
        }

        /** 
         * @see javax.servlet.http.HttpSessionActivationListener#sessionDidActivate(javax.servlet.http.HttpSessionEvent)
         */
        public void sessionDidActivate(HttpSessionEvent se)
        {
           ++activates;
        }
        
        public void assertPassivatesEquals (int expected)
        {
            assertEquals(expected, passivates);
        }
        
        public void assertActivatesEquals (int expected)
        {
            assertEquals(expected, activates);
        }
        
        public void assertBindsEquals (int expected)
        {
            assertEquals(expected, binds);
        }
        
        public void assertUnbindsEquals (int expected)
        {
            assertEquals(expected, unbinds);
        }
        

        /** 
         * @see javax.servlet.http.HttpSessionBindingListener#valueBound(javax.servlet.http.HttpSessionBindingEvent)
         */
        public void valueBound(HttpSessionBindingEvent event)
        {
            ++binds;
        }

        /** 
         * @see javax.servlet.http.HttpSessionBindingListener#valueUnbound(javax.servlet.http.HttpSessionBindingEvent)
         */
        public void valueUnbound(HttpSessionBindingEvent event)
        {
            ++unbinds;
        }      
    }
    
    public static class TestDirtyServlet extends HttpServlet
    {
        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
        {
            String action = request.getParameter("action");
            
            if ("create".equals(action))
            {
                HttpSession session = request.getSession(true);
                return;
            }
            
            if ("setA".equals(action))
            {
                HttpSession session = request.getSession(false);
                if (session == null)
                    throw new ServletException("Session is null for action=change");

                session.setAttribute(THE_NAME, A_VALUE);
                return;
            }
            
            if ("setB".equals(action))
            {
                HttpSession session = request.getSession(false);
                if (session == null)
                    throw new ServletException("Session does not exist");
                session.setAttribute(THE_NAME, B_VALUE);
                return;
            }
        }
    }
    
}
