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

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.TimeUnit;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;

import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.http.HttpClientTransportOverHTTP;
import org.eclipse.jetty.client.http.HttpDestinationOverHTTP;
import org.eclipse.jetty.client.util.FutureResponseListener;
import org.eclipse.jetty.http.HttpStatus;
import org.eclipse.jetty.toolchain.test.TestTracker;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.junit.After;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class TLSServerConnectionCloseTest
{
    @Parameterized.Parameters(name = "CloseMode: {0}")
    public static Object[] parameters()
    {
        return new Object[]{CloseMode.NONE, CloseMode.CLOSE, CloseMode.ABRUPT};
    }

    @Rule
    public final TestTracker tracker = new TestTracker();
    private HttpClient client;
    private final CloseMode closeMode;

    public TLSServerConnectionCloseTest(CloseMode closeMode)
    {
        this.closeMode = closeMode;
    }

    private void startClient() throws Exception
    {
        SslContextFactory sslContextFactory = new SslContextFactory();
        sslContextFactory.setEndpointIdentificationAlgorithm("");
        sslContextFactory.setKeyStorePath("src/test/resources/keystore.jks");
        sslContextFactory.setKeyStorePassword("storepwd");
        sslContextFactory.setTrustStorePath("src/test/resources/truststore.jks");
        sslContextFactory.setTrustStorePassword("storepwd");

        QueuedThreadPool clientThreads = new QueuedThreadPool();
        clientThreads.setName("client");
        client = new HttpClient(new HttpClientTransportOverHTTP(1), sslContextFactory);
        client.setExecutor(clientThreads);
        client.start();
    }

    @After
    public void dispose() throws Exception
    {
        if (client != null)
            client.stop();
    }

    @Test
    public void testServerSendsConnectionCloseWithoutContent() throws Exception
    {
        testServerSendsConnectionClose(false, "");
    }

    @Test
    public void testServerSendsConnectionCloseWithContent() throws Exception
    {
        testServerSendsConnectionClose(false, "data");
    }

    @Test
    public void testServerSendsConnectionCloseWithChunkedContent() throws Exception
    {
        testServerSendsConnectionClose(true, "data");
    }

    private void testServerSendsConnectionClose(boolean chunked, String content) throws Exception
    {
        ServerSocket server = new ServerSocket(0);
        int port = server.getLocalPort();

        startClient();

        Request request = client.newRequest("localhost", port).scheme("https").path("/ctx/path");
        FutureResponseListener listener = new FutureResponseListener(request);
        request.send(listener);

        Socket socket = server.accept();
        SSLContext sslContext = client.getSslContextFactory().getSslContext();
        SSLSocket sslSocket = (SSLSocket)sslContext.getSocketFactory().createSocket(socket, "localhost", port, false);
        sslSocket.setUseClientMode(false);
        sslSocket.startHandshake();

        InputStream input = sslSocket.getInputStream();
        consumeRequest(input);

        OutputStream output = sslSocket.getOutputStream();
        String serverResponse = "" +
                "HTTP/1.1 200 OK\r\n" +
                "Connection: close\r\n";
        if (chunked)
        {
            serverResponse += "" +
                    "Transfer-Encoding: chunked\r\n" +
                    "\r\n";
                    for (int i = 0; i < 2; ++i)
                    {
                        serverResponse +=
                                Integer.toHexString(content.length()) + "\r\n" +
                                content + "\r\n";
                    }
            serverResponse += "" +
                    "0\r\n" +
                    "\r\n";
        }
        else
        {
            serverResponse += "Content-Length: " + content.length() + "\r\n";
            serverResponse += "\r\n";
            serverResponse += content;
        }

        output.write(serverResponse.getBytes("UTF-8"));
        output.flush();

        switch (closeMode)
        {
            case NONE:
            {
                break;
            }
            case CLOSE:
            {
                sslSocket.close();
                break;
            }
            case ABRUPT:
            {
                socket.shutdownOutput();
                break;
            }
            default:
            {
                throw new IllegalStateException();
            }
        }

        ContentResponse response = listener.get(5, TimeUnit.SECONDS);
        Assert.assertEquals(HttpStatus.OK_200, response.getStatus());

        // Give some time to process the connection.
        Thread.sleep(1000);

        // Connection should have been removed from pool.
        HttpDestinationOverHTTP destination = (HttpDestinationOverHTTP)client.getDestination("http", "localhost", port);
        DuplexConnectionPool connectionPool = destination.getConnectionPool();
        Assert.assertEquals(0, connectionPool.getConnectionCount());
        Assert.assertEquals(0, connectionPool.getIdleConnectionCount());
        Assert.assertEquals(0, connectionPool.getActiveConnectionCount());
    }

    private boolean consumeRequest(InputStream input) throws IOException
    {
        int crlfs = 0;
        while (true)
        {
            int read = input.read();
            if (read < 0)
                return true;
            if (read == '\r' || read == '\n')
                ++crlfs;
            else
                crlfs = 0;
            if (crlfs == 4)
                return false;
        }
    }

    private enum CloseMode
    {
        NONE, CLOSE, ABRUPT
    }
}
