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

import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.StringReader;

import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

import org.eclipse.jetty.http.HttpParser;
import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.QuietServletException;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.util.log.StacklessLogging;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

/**
 * This tests the correct functioning of the AsyncContext
 *
 * tests for #371649 and #371635
 */
public class AsyncContextTest
{

    private Server _server;
    private ServletContextHandler _contextHandler;
    private LocalConnector _connector;

    @Before
    public void setUp() throws Exception
    {
        _server = new Server();
        _contextHandler = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
        _connector = new LocalConnector(_server);
        _connector.setIdleTimeout(5000);
        _connector.getConnectionFactory(HttpConnectionFactory.class).getHttpConfiguration().setSendDateHeader(false);
        _server.setConnectors(new Connector[]
        { _connector });

        _contextHandler.setContextPath("/ctx");
        _contextHandler.addServlet(new ServletHolder(new TestServlet()),"/servletPath");
        _contextHandler.addServlet(new ServletHolder(new TestServlet()),"/path with spaces/servletPath");
        _contextHandler.addServlet(new ServletHolder(new TestServlet2()),"/servletPath2");
        _contextHandler.addServlet(new ServletHolder(new TestStartThrowServlet()),"/startthrow/*");
        _contextHandler.addServlet(new ServletHolder(new ForwardingServlet()),"/forward");
        _contextHandler.addServlet(new ServletHolder(new AsyncDispatchingServlet()),"/dispatchingServlet");
        _contextHandler.addServlet(new ServletHolder(new ExpireServlet()),"/expire/*");
        _contextHandler.addServlet(new ServletHolder(new BadExpireServlet()),"/badexpire/*");
        _contextHandler.addServlet(new ServletHolder(new ErrorServlet()),"/error/*");
        
        ErrorPageErrorHandler error_handler = new ErrorPageErrorHandler();
        _contextHandler.setErrorHandler(error_handler);
        error_handler.addErrorPage(500,"/error/500");
        error_handler.addErrorPage(IOException.class.getName(),"/error/IOE");

        HandlerList handlers = new HandlerList();
        handlers.setHandlers(new Handler[]
        { _contextHandler, new DefaultHandler() });

        _server.setHandler(handlers);
        _server.start();
    }

    @After
    public void after() throws Exception
    {
        _server.stop();
    }

    @Test
    public void testSimpleAsyncContext() throws Exception
    {
        String request = "GET /ctx/servletPath HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n"
                + "Connection: close\r\n" + "\r\n";
        String responseString = _connector.getResponses(request);


        BufferedReader br = parseHeader(responseString);

        Assert.assertEquals("servlet gets right path", "doGet:getServletPath:/servletPath", br.readLine());
        Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath",br.readLine());
        Assert.assertEquals("async context gets right path in async","async:run:attr:servletPath:/servletPath",br.readLine());
   
    }

    @Test
    public void testStartThrow() throws Exception
    {
        String request = 
          "GET /ctx/startthrow HTTP/1.1\r\n" + 
          "Host: localhost\r\n" + 
          "Connection: close\r\n" + 
          "\r\n";
        String responseString = _connector.getResponses(request);

        BufferedReader br = new BufferedReader(new StringReader(responseString));

        assertEquals("HTTP/1.1 500 Server Error",br.readLine());
        br.readLine();// connection close
        br.readLine();// server
        br.readLine();// empty

        Assert.assertEquals("error servlet","ERROR: /error",br.readLine());
        Assert.assertEquals("error servlet","PathInfo= /IOE",br.readLine());
        Assert.assertEquals("error servlet","EXCEPTION: org.eclipse.jetty.server.QuietServletException: java.io.IOException: Test",br.readLine());
    }

    @Test
    public void testStartDispatchThrow() throws Exception
    {
        String request = "GET /ctx/startthrow?dispatch=true HTTP/1.1\r\n" + 
           "Host: localhost\r\n" + 
           "Content-Type: application/x-www-form-urlencoded\r\n" + 
           "Connection: close\r\n" + 
           "\r\n";
        String responseString = _connector.getResponses(request);

        BufferedReader br = new BufferedReader(new StringReader(responseString));

        assertEquals("HTTP/1.1 500 Server Error",br.readLine());
        br.readLine();// connection close
        br.readLine();// server
        br.readLine();// empty
        Assert.assertEquals("error servlet","ERROR: /error",br.readLine());
        Assert.assertEquals("error servlet","PathInfo= /IOE",br.readLine());
        Assert.assertEquals("error servlet","EXCEPTION: org.eclipse.jetty.server.QuietServletException: java.io.IOException: Test",br.readLine());
    }
    
    @Test
    public void testStartCompleteThrow() throws Exception
    {
        String request = "GET /ctx/startthrow?complete=true HTTP/1.1\r\n" + 
           "Host: localhost\r\n" + 
           "Content-Type: application/x-www-form-urlencoded\r\n" + 
           "Connection: close\r\n" + 
           "\r\n";
        String responseString = _connector.getResponses(request);

        BufferedReader br = new BufferedReader(new StringReader(responseString));

        assertEquals("HTTP/1.1 500 Server Error",br.readLine());
        br.readLine();// connection close
        br.readLine();// server
        br.readLine();// empty
        Assert.assertEquals("error servlet","ERROR: /error",br.readLine());
        Assert.assertEquals("error servlet","PathInfo= /IOE",br.readLine());
        Assert.assertEquals("error servlet","EXCEPTION: org.eclipse.jetty.server.QuietServletException: java.io.IOException: Test",br.readLine());
    }
    
    @Test
    public void testStartFlushCompleteThrow() throws Exception
    {
        try(StacklessLogging stackless = new StacklessLogging(HttpChannel.class))
        {
            String request = "GET /ctx/startthrow?flush=true&complete=true HTTP/1.1\r\n" + 
                    "Host: localhost\r\n" + 
                    "Content-Type: application/x-www-form-urlencoded\r\n" + 
                    "Connection: close\r\n" + 
                    "\r\n";
            String responseString = _connector.getResponses(request);

            BufferedReader br = new BufferedReader(new StringReader(responseString));

            assertEquals("HTTP/1.1 200 OK",br.readLine());
            br.readLine();// connection close
            br.readLine();// server
            br.readLine();// empty

            Assert.assertEquals("error servlet","completeBeforeThrow",br.readLine());
        }
    }
    
    @Test
    public void testDispatchAsyncContext() throws Exception
    {
        String request = "GET /ctx/servletPath?dispatch=true HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n"
                + "Connection: close\r\n" + "\r\n";
        String responseString = _connector.getResponses(request);

        BufferedReader br = parseHeader(responseString);

        Assert.assertEquals("servlet gets right path","doGet:getServletPath:/servletPath2",br.readLine());
        Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath2",br.readLine());
        Assert.assertEquals("servlet path attr is original","async:run:attr:servletPath:/servletPath",br.readLine());
        Assert.assertEquals("path info attr is correct","async:run:attr:pathInfo:null",br.readLine());
        Assert.assertEquals("query string attr is correct","async:run:attr:queryString:dispatch=true",br.readLine());
        Assert.assertEquals("context path attr is correct","async:run:attr:contextPath:/ctx",br.readLine());
        Assert.assertEquals("request uri attr is correct","async:run:attr:requestURI:/ctx/servletPath",br.readLine());
    }

    @Test
    public void testDispatchAsyncContextEncodedPathAndQueryString() throws Exception
    {
        String request = "GET /ctx/path%20with%20spaces/servletPath?dispatch=true&queryStringWithEncoding=space%20space HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n"
                + "Connection: close\r\n" + "\r\n";
        String responseString = _connector.getResponses(request);

        BufferedReader br = parseHeader(responseString);

        assertThat("servlet gets right path",br.readLine(),equalTo("doGet:getServletPath:/servletPath2"));
        assertThat("async context gets right path in get",br.readLine(), equalTo("doGet:async:getServletPath:/servletPath2"));
        assertThat("servlet path attr is original",br.readLine(),equalTo("async:run:attr:servletPath:/path with spaces/servletPath"));
        assertThat("path info attr is correct",br.readLine(),equalTo("async:run:attr:pathInfo:null"));
        assertThat("query string attr is correct",br.readLine(),equalTo("async:run:attr:queryString:dispatch=true&queryStringWithEncoding=space%20space"));
        assertThat("context path attr is correct",br.readLine(),equalTo("async:run:attr:contextPath:/ctx"));
        assertThat("request uri attr is correct",br.readLine(),equalTo("async:run:attr:requestURI:/ctx/path%20with%20spaces/servletPath"));
    }

    @Test
    public void testSimpleWithContextAsyncContext() throws Exception
    {
        String request = "GET /ctx/servletPath HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n"
                + "Connection: close\r\n" + "\r\n";

        String responseString = _connector.getResponses(request);

        BufferedReader br = parseHeader(responseString);

        Assert.assertEquals("servlet gets right path","doGet:getServletPath:/servletPath",br.readLine());
        Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath",br.readLine());
        Assert.assertEquals("async context gets right path in async","async:run:attr:servletPath:/servletPath",br.readLine());
    }

    @Test
    public void testDispatchWithContextAsyncContext() throws Exception
    {
        String request = "GET /ctx/servletPath?dispatch=true HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n"
                + "Connection: close\r\n" + "\r\n";

        String responseString = _connector.getResponses(request);

        BufferedReader br = parseHeader(responseString);

        Assert.assertEquals("servlet gets right path","doGet:getServletPath:/servletPath2",br.readLine());
        Assert.assertEquals("async context gets right path in get","doGet:async:getServletPath:/servletPath2",br.readLine());
        Assert.assertEquals("servlet path attr is original","async:run:attr:servletPath:/servletPath",br.readLine());
        Assert.assertEquals("path info attr is correct","async:run:attr:pathInfo:null",br.readLine());
        Assert.assertEquals("query string attr is correct","async:run:attr:queryString:dispatch=true",br.readLine());
        Assert.assertEquals("context path attr is correct","async:run:attr:contextPath:/ctx",br.readLine());
        Assert.assertEquals("request uri attr is correct","async:run:attr:requestURI:/ctx/servletPath",br.readLine());
    }

    @Test
    public void testDispatch() throws Exception
    {
        String request = "GET /ctx/forward HTTP/1.1\r\n" + "Host: localhost\r\n" + "Content-Type: application/x-www-form-urlencoded\r\n" + "Connection: close\r\n"
                + "\r\n";

        String responseString = _connector.getResponses(request);
        BufferedReader br = parseHeader(responseString);
        assertThat("!ForwardingServlet",br.readLine(),equalTo("Dispatched back to ForwardingServlet"));
    }

    @Test
    public void testDispatchRequestResponse() throws Exception
    {
        String request = "GET /ctx/forward?dispatchRequestResponse=true HTTP/1.1\r\n" + 
           "Host: localhost\r\n" + 
           "Content-Type: application/x-www-form-urlencoded\r\n" + 
           "Connection: close\r\n" + 
           "\r\n";

        String responseString = _connector.getResponses(request);

        BufferedReader br = parseHeader(responseString);

        assertThat("!AsyncDispatchingServlet",br.readLine(),equalTo("Dispatched back to AsyncDispatchingServlet"));
    }

    private BufferedReader parseHeader(String responseString) throws IOException
    {
        BufferedReader br = new BufferedReader(new StringReader(responseString));

        assertEquals("HTTP/1.1 200 OK",br.readLine());

        br.readLine();// connection close
        br.readLine();// server
        br.readLine();// empty
        return br;
    }

    private class ForwardingServlet extends HttpServlet
    {
        private static final long serialVersionUID = 1L;

        @Override
        protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException
        {
            if (request.getDispatcherType() == DispatcherType.ASYNC)
            {
                response.getOutputStream().print("Dispatched back to ForwardingServlet");
            }
            else
            {
                request.getRequestDispatcher("/dispatchingServlet").forward(request,response);
            }
        }
    }

    private class AsyncDispatchingServlet extends HttpServlet
    {
        private static final long serialVersionUID = 1L;
        
        @Override
        protected void doGet(HttpServletRequest req, final HttpServletResponse response) throws ServletException, IOException
        {
            Request request = (Request)req;
            if (request.getDispatcherType() == DispatcherType.ASYNC)
            {
                response.getOutputStream().print("Dispatched back to AsyncDispatchingServlet");
            }
            else
            {
                boolean wrapped = false;
                final AsyncContext asyncContext;
                if (request.getParameter("dispatchRequestResponse") != null)
                {
                    wrapped = true;
                    asyncContext = request.startAsync(request, new Wrapper(response));
                }
                else
                {
                    asyncContext = request.startAsync();
                }

                new Thread(new DispatchingRunnable(asyncContext, wrapped)).start();
            }
        }
    }

    @Test
    public void testExpire() throws Exception
    {
        String request = "GET /ctx/expire HTTP/1.1\r\n" + 
                "Host: localhost\r\n" + 
                "Content-Type: application/x-www-form-urlencoded\r\n" +
                "Connection: close\r\n" + 
                "\r\n";
        String responseString = _connector.getResponses(request);
               
        BufferedReader br = new BufferedReader(new StringReader(responseString));

        assertEquals("HTTP/1.1 500 Async Timeout",br.readLine());

        br.readLine();// connection close
        br.readLine();// server
        br.readLine();// empty

        Assert.assertEquals("error servlet","ERROR: /error",br.readLine());
    }

    @Test
    public void testBadExpire() throws Exception
    {
        String request = "GET /ctx/badexpire HTTP/1.1\r\n" + 
          "Host: localhost\r\n" + 
          "Content-Type: application/x-www-form-urlencoded\r\n" +
          "Connection: close\r\n" + 
          "\r\n";
        String responseString = _connector.getResponses(request);
        
        BufferedReader br = new BufferedReader(new StringReader(responseString));

        assertEquals("HTTP/1.1 500 Server Error",br.readLine());
        br.readLine();// connection close
        br.readLine();// server
        br.readLine();// empty

        Assert.assertEquals("error servlet","ERROR: /error",br.readLine());
        Assert.assertEquals("error servlet","PathInfo= /500",br.readLine());
        Assert.assertEquals("error servlet","EXCEPTION: java.lang.RuntimeException: TEST",br.readLine());
    }

    private class DispatchingRunnable implements Runnable
    {
        private AsyncContext asyncContext;
        private boolean wrapped;

        public DispatchingRunnable(AsyncContext asyncContext, boolean wrapped)
        {
            this.asyncContext = asyncContext;
            this.wrapped = wrapped;
        }

        public void run()
        {
            if (wrapped)
                assertTrue(asyncContext.getResponse() instanceof Wrapper);
            asyncContext.dispatch();
        }
    }

    @After
    public void tearDown() throws Exception
    {
        _server.stop();
        _server.join();
    }


    private class ErrorServlet extends HttpServlet
    {
        private static final long serialVersionUID = 1L;

        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
        {
            response.getOutputStream().print("ERROR: " + request.getServletPath() + "\n");
            response.getOutputStream().print("PathInfo= " + request.getPathInfo() + "\n");
            if (request.getAttribute(RequestDispatcher.ERROR_EXCEPTION)!=null)
                response.getOutputStream().print("EXCEPTION: " + request.getAttribute(RequestDispatcher.ERROR_EXCEPTION) + "\n");
        }
    }
    
    private class ExpireServlet extends HttpServlet
    {
        private static final long serialVersionUID = 1L;

        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
        {
            if (request.getDispatcherType()==DispatcherType.REQUEST)
            {
                AsyncContext asyncContext = request.startAsync();
                asyncContext.setTimeout(100);
            }
        }
    }
    
    private class BadExpireServlet extends HttpServlet
    {
        private static final long serialVersionUID = 1L;

        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
        {
            if (request.getDispatcherType()==DispatcherType.REQUEST)
            {
                AsyncContext asyncContext = request.startAsync();
                asyncContext.addListener(new AsyncListener()
                {
                    @Override
                    public void onTimeout(AsyncEvent event) throws IOException
                    {
                        throw new RuntimeException("TEST");
                    }
                    
                    @Override
                    public void onStartAsync(AsyncEvent event) throws IOException
                    {                      
                    }
                    
                    @Override
                    public void onError(AsyncEvent event) throws IOException
                    {                        
                    }
                    
                    @Override
                    public void onComplete(AsyncEvent event) throws IOException
                    {                        
                    }
                });
                asyncContext.setTimeout(100);
            }
        }
    }
    
    private class TestServlet extends HttpServlet
    {
        private static final long serialVersionUID = 1L;

        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
        {
            if (request.getParameter("dispatch") != null)
            {
                AsyncContext asyncContext = request.startAsync(request,response);
                asyncContext.dispatch("/servletPath2");
            }
            else
            {
                response.getOutputStream().print("doGet:getServletPath:" + request.getServletPath() + "\n");
                AsyncContext asyncContext = request.startAsync(request,response);
                response.getOutputStream().print("doGet:async:getServletPath:" + ((HttpServletRequest)asyncContext.getRequest()).getServletPath() + "\n");
                asyncContext.start(new AsyncRunnable(asyncContext));

            }
        }
    }

    private class TestServlet2 extends HttpServlet
    {
        private static final long serialVersionUID = 1L;

        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
        {
            response.getOutputStream().print("doGet:getServletPath:" + request.getServletPath() + "\n");
            AsyncContext asyncContext = request.startAsync(request, response);
            response.getOutputStream().print("doGet:async:getServletPath:" + ((HttpServletRequest)asyncContext.getRequest()).getServletPath() + "\n");
            asyncContext.start(new AsyncRunnable(asyncContext));
        }
    }
    
    private class TestStartThrowServlet extends HttpServlet
    {
        private static final long serialVersionUID = 1L;

        @Override
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
        {
            if (request.getDispatcherType()==DispatcherType.REQUEST)
            {
                request.startAsync(request, response);
                
                if (Boolean.valueOf(request.getParameter("dispatch")))
                {
                    request.getAsyncContext().dispatch();
                }

                if (Boolean.valueOf(request.getParameter("complete")))
                {
                    response.getOutputStream().write("completeBeforeThrow".getBytes());
                    if (Boolean.valueOf(request.getParameter("flush")))
                        response.flushBuffer();
                    request.getAsyncContext().complete();
                }
                    
                throw new QuietServletException(new IOException("Test"));
            }
        }
    }

    private class AsyncRunnable implements Runnable
    {
        private AsyncContext _context;

        public AsyncRunnable(AsyncContext context)
        {
            _context = context;
        }

        @Override
        public void run()
        {
            HttpServletRequest req = (HttpServletRequest)_context.getRequest();

            try
            {
                _context.getResponse().getOutputStream().print("async:run:attr:servletPath:" + req.getAttribute(AsyncContext.ASYNC_SERVLET_PATH) + "\n");
                _context.getResponse().getOutputStream().print("async:run:attr:pathInfo:" + req.getAttribute(AsyncContext.ASYNC_PATH_INFO) + "\n");
                _context.getResponse().getOutputStream().print("async:run:attr:queryString:" + req.getAttribute(AsyncContext.ASYNC_QUERY_STRING) + "\n");
                _context.getResponse().getOutputStream().print("async:run:attr:contextPath:" + req.getAttribute(AsyncContext.ASYNC_CONTEXT_PATH) + "\n");
                _context.getResponse().getOutputStream().print("async:run:attr:requestURI:" + req.getAttribute(AsyncContext.ASYNC_REQUEST_URI) + "\n");
            }
            catch (IOException e)
            {
                e.printStackTrace();
            }
            _context.complete();
        }
    }

    private class Wrapper extends HttpServletResponseWrapper
    {
        public Wrapper (HttpServletResponse response)
        {
            super(response);
        }
    }


}
