/*
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You under the Apache License, Version 2.0
 *  (the "License"); you may not use this file except in compliance with
 *  the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.apache.coyote;

import java.io.IOException;

import javax.servlet.AsyncContext;
import javax.servlet.ReadListener;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.WriteListener;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.junit.Assert;
import org.junit.Test;

import org.apache.catalina.Context;
import org.apache.catalina.Wrapper;
import org.apache.catalina.startup.SimpleHttpClient;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.startup.TomcatBaseTest;

public class TestIoTimeouts extends TomcatBaseTest {

    @Test
    public void testNonBlockingReadWithNoTimeout() {
        // Sends complete request in 3 packets
        ChunkedClient client = new ChunkedClient(true);
        client.doRequest();
        Assert.assertTrue(client.isResponse200());
        Assert.assertTrue(client.isResponseBodyOK());
        Assert.assertNull(EchoListener.t);
    }


    @Test
    public void testNonBlockingReadTimeout() {
        // Sends incomplete request (no end chunk) so read times out
        ChunkedClient client = new ChunkedClient(false);
        client.doRequest();
        Assert.assertFalse(client.isResponse200());
        Assert.assertFalse(client.isResponseBodyOK());
        // Socket will be closed before the error handler runs. Closing the
        // socket triggers the client code's return from the doRequest() method
        // above so we need to wait at this point for the error handler to be
        // triggered.
        int count = 0;
        // Shouldn't need to wait long but allow plenty of time as the CI
        // systems are sometimes slow.
        while (count < 100 && EchoListener.t == null) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // Ignore
            }
            count++;
        }
        Assert.assertNotNull(EchoListener.t);
    }


    private class ChunkedClient extends SimpleHttpClient {

        private final boolean sendEndChunk;


        public ChunkedClient(boolean sendEndChunk) {
            this.sendEndChunk = sendEndChunk;
        }


        private Exception doRequest() {

            Tomcat tomcat = getTomcatInstance();

            Context root = tomcat.addContext("", TEMP_DIR);
            Wrapper w = Tomcat.addServlet(root, "Test", new NonBlockingEchoServlet());
            w.setAsyncSupported(true);
            root.addServletMappingDecoded("/test", "Test");

            try {
                tomcat.start();
                setPort(tomcat.getConnector().getLocalPort());

                // Open connection
                connect();

                int packetCount = 2;
                if (sendEndChunk) {
                    packetCount++;
                }

                String[] request = new String[packetCount];
                request[0] =
                    "POST /test HTTP/1.1" + CRLF +
                    "Host: localhost:8080" + CRLF +
                    "Transfer-Encoding: chunked" + CRLF +
                    "Connection: close" + CRLF +
                    CRLF;
                request[1] =
                        "b8" + CRLF +
                        "{" + CRLF +
                        "  \"tenantId\": \"dotCom\", "  + CRLF +
                        "  \"locale\": \"en-US\", "  + CRLF +
                        "  \"defaultZoneId\": \"25\", "  + CRLF +
                        "  \"itemIds\": [\"StaplesUSCAS/en-US/2/<EOF>/<EOF>\"] , "  + CRLF +
                        "  \"assetStoreId\": \"5051\", "  + CRLF +
                        "  \"zipCode\": \"98109\"" + CRLF +
                        "}" + CRLF;
                if (sendEndChunk) {
                    request[2] =
                            "0" + CRLF +
                            CRLF;
                }

                setRequest(request);
                processRequest(); // blocks until response has been read

                // Close the connection
                disconnect();
            } catch (Exception e) {
                return e;
            }
            return null;
        }

        @Override
        public boolean isResponseBodyOK() {
            if (getResponseBody() == null) {
                return false;
            }
            if (!getResponseBody().contains("98109")) {
                return false;
            }
            return true;
        }

    }


    private static class NonBlockingEchoServlet extends HttpServlet {

        private static final long serialVersionUID = 1L;

        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                throws ServletException, IOException {

            // Need to be in async mode to use non-blocking I/O
            AsyncContext ac = req.startAsync();
            ac.setTimeout(10000);

            ServletInputStream sis = null;
            ServletOutputStream sos = null;

            try {
                sis = req.getInputStream();
                sos = resp.getOutputStream();
            } catch (IOException ioe) {
                throw new ServletException(ioe);
            }

            EchoListener listener = new EchoListener(ac, sis, sos);
            sis.setReadListener(listener);
            sos.setWriteListener(listener);
        }
    }


    private static class EchoListener implements ReadListener, WriteListener {

        private static volatile Throwable t;

        private final AsyncContext ac;
        private final ServletInputStream sis;
        private final ServletOutputStream sos;
        private final byte[] buffer = new byte[8192];

        public EchoListener(AsyncContext ac, ServletInputStream sis, ServletOutputStream sos) {
            t = null;
            this.ac = ac;
            this.sis = sis;
            this.sos = sos;
        }

        @Override
        public void onWritePossible() throws IOException {
            if (sis.isFinished()) {
                sos.flush();
                ac.complete();
                return;
            }
            while (sis.isReady()) {
                int read = sis.read(buffer);
                if (read > 0) {
                    sos.write(buffer, 0, read);
                    if (!sos.isReady()) {
                        break;
                    }
                }
            }
        }

        @Override
        public void onDataAvailable() throws IOException {
            if (sos.isReady()) {
                onWritePossible();
            }
        }

        @Override
        public void onAllDataRead() throws IOException {
            if (sos.isReady()) {
                onWritePossible();
            }
        }

        @Override
        public void onError(Throwable throwable) {
            t = throwable;
            ac.complete();
        }
    }
}
