//
//  ========================================================================
//  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 java.io.IOException;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;

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

import org.eclipse.jetty.server.HttpChannel;
import org.eclipse.jetty.server.LocalConnector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.log.StacklessLogging;
import org.hamcrest.Matchers;
import org.junit.*;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

public class PostServletTest
{
    private static final Logger LOG = Log.getLogger(PostServletTest.class);
    private static final AtomicBoolean posted = new AtomicBoolean(false);
    private static final AtomicReference<Throwable> ex0=new AtomicReference<>();
    private static final AtomicReference<Throwable> ex1=new AtomicReference<>();
    private static CountDownLatch complete;

    public static class BasicReadPostServlet extends HttpServlet
    {
        protected void doPost(HttpServletRequest request, HttpServletResponse response)
        {
            posted.set(true);
            byte[] buffer = new byte[1024];
            try
            {
                int len=request.getInputStream().read(buffer);
                while(len>0)
                {
                    response.getOutputStream().println("read "+len);
                    response.getOutputStream().flush();
                    len = request.getInputStream().read(buffer);
                }
            }
            catch (Exception e0)
            {
                ex0.set(e0);
                try
                {
                    // this read-call should fail immediately
                    request.getInputStream().read(buffer);
                }
                catch (Exception e1)
                {
                    ex1.set(e1);
                    LOG.warn(e1.toString());
                }
            }
            finally
            {
                complete.countDown();
            }
        }
    }

    private Server server;
    private LocalConnector connector;

    @Before
    public void startServer() throws Exception
    {
        complete=new CountDownLatch(1);
        ex0.set(null);
        ex1.set(null);
        posted.set(false);
        server = new Server();
        connector = new LocalConnector(server);
        server.addConnector(connector);

        ServletContextHandler context = new ServletContextHandler();
        context.setContextPath("/");
        context.addServlet(BasicReadPostServlet.class, "/post");

        server.setHandler(context);

        server.start();
    }

    @After
    public void stopServer() throws Exception
    {
        this.server.stop();
    }

    @Test
    public void testGoodPost() throws Exception
    {
        StringBuilder req = new StringBuilder();
        req.append("POST /post HTTP/1.1\r\n");
        req.append("Host: localhost\r\n");
        req.append("Transfer-Encoding: chunked\r\n");
        req.append("\r\n");
        req.append("6\r\n");
        req.append("Hello ");
        req.append("\r\n");
        req.append("7\r\n");
        req.append("World!\n");
        req.append("\r\n");
        req.append("0\r\n");
        req.append("\r\n");

        String resp = connector.getResponses(req.toString(),1,TimeUnit.SECONDS);

        assertThat("resp", resp, containsString("HTTP/1.1 200 OK"));
        assertThat("resp", resp, containsString("chunked"));
        assertThat("resp", resp, containsString("read 6"));
        assertThat("resp", resp, containsString("read 7"));
        assertThat("resp", resp, containsString("\r\n0\r\n"));

        assertThat(ex0.get(),nullValue());
        assertThat(ex1.get(),nullValue());
    }

    @Test
    public void testBadPost() throws Exception
    {
        StringBuilder req = new StringBuilder(16*1024);
        req.append("POST /post HTTP/1.1\r\n");
        req.append("Host: localhost\r\n");
        req.append("Transfer-Encoding: chunked\r\n");
        req.append("\r\n");
        // intentionally bad (not a valid chunked char here)
        for (int i=1024;i-->0;)
            req.append("xxxxxxxxxxxx");
        req.append("\r\n");
        req.append("\r\n");

        String resp = connector.getResponse(req.toString());
        assertThat(resp,startsWith("HTTP/1.1 200 OK")); // exception eaten by handler
        assertTrue(complete.await(5,TimeUnit.SECONDS));
        assertThat(ex0.get(),not(nullValue()));
        assertThat(ex1.get(),not(nullValue()));
    }

    @Test
    public void testDeferredBadPost() throws Exception
    {
        StringBuilder req = new StringBuilder(16*1024);
        req.append("POST /post HTTP/1.1\r\n");
        req.append("Host: localhost\r\n");
        req.append("Transfer-Encoding: chunked\r\n");
        req.append("\r\n");

        LocalConnector.LocalEndPoint endp=connector.executeRequest(req.toString());
        Thread.sleep(1000);
        assertFalse(posted.get());

        req.setLength(0);
        // intentionally bad (not a valid chunked char here)
        for (int i=1024;i-->0;)
            req.append("xxxxxxxxxxxx");
        req.append("\r\n");
        req.append("\r\n");

        endp.addInput(req.toString());

        endp.waitUntilClosedOrIdleFor(1,TimeUnit.SECONDS);
        String resp = endp.takeOutputString();

        assertThat(resp,startsWith("HTTP/1.1 200 OK")); // exception eaten by handler
        assertTrue(complete.await(5,TimeUnit.SECONDS));
        assertThat(ex0.get(),not(nullValue()));
        assertThat(ex1.get(),not(nullValue()));
    }


    @Test
    public void testBadSplitPost() throws Exception
    {
        StringBuilder req = new StringBuilder();
        req.append("POST /post HTTP/1.1\r\n");
        req.append("Host: localhost\r\n");
        req.append("Connection: close\r\n");
        req.append("Transfer-Encoding: chunked\r\n");
        req.append("\r\n");
        req.append("6\r\n");
        req.append("Hello ");
        req.append("\r\n");

        try (StacklessLogging scope = new StacklessLogging(ServletHandler.class))
        {
            LocalConnector.LocalEndPoint endp=connector.executeRequest(req.toString());
            req.setLength(0);

            while(!posted.get())
                Thread.sleep(100);
            Thread.sleep(100);
            req.append("x\r\n");
            req.append("World\n");
            req.append("\r\n");
            req.append("0\r\n");
            req.append("\r\n");
            endp.addInput(req.toString());

            endp.waitUntilClosedOrIdleFor(1,TimeUnit.SECONDS);
            String resp = endp.takeOutputString();
            assertThat("resp", resp, containsString("HTTP/1.1 200 "));
            assertThat("resp", resp, not(containsString("\r\n0\r\n"))); // aborted
        }
        assertTrue(complete.await(5,TimeUnit.SECONDS));
        assertThat(ex0.get(),not(nullValue()));
        assertThat(ex1.get(),not(nullValue()));
    }

}
