//
//  ========================================================================
//  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.spdy.server.proxy;

import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.StringContentProvider;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.spdy.api.BytesDataInfo;
import org.eclipse.jetty.spdy.api.DataInfo;
import org.eclipse.jetty.spdy.api.GoAwayResultInfo;
import org.eclipse.jetty.spdy.api.PushInfo;
import org.eclipse.jetty.spdy.api.ReplyInfo;
import org.eclipse.jetty.spdy.api.RstInfo;
import org.eclipse.jetty.spdy.api.SPDY;
import org.eclipse.jetty.spdy.api.Session;
import org.eclipse.jetty.spdy.api.Stream;
import org.eclipse.jetty.spdy.api.StreamFrameListener;
import org.eclipse.jetty.spdy.api.StreamStatus;
import org.eclipse.jetty.spdy.api.SynInfo;
import org.eclipse.jetty.spdy.api.server.ServerSessionFrameListener;
import org.eclipse.jetty.spdy.client.SPDYClient;
import org.eclipse.jetty.spdy.http.HTTPSPDYHeader;
import org.eclipse.jetty.spdy.server.SPDYServerConnectionFactory;
import org.eclipse.jetty.spdy.server.SPDYServerConnector;
import org.eclipse.jetty.toolchain.test.TestTracker;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Fields;
import org.eclipse.jetty.util.Promise;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

@RunWith(Parameterized.class)
public class ProxyHTTPToSPDYTest
{
    @Parameterized.Parameters
    public static Collection<Short[]> parameters()
    {
        return Arrays.asList(new Short[]{SPDY.V2}, new Short[]{SPDY.V3});
    }

    @Rule
    public final TestTracker tracker = new TestTracker();
    private final short version;
    private HttpClient httpClient;
    private HttpClient httpClient2;
    private SPDYClient.Factory factory;
    private Server server;
    private Server proxy;
    private ServerConnector proxyConnector;

    public ProxyHTTPToSPDYTest(short version)
    {
        this.version = version;
    }

    protected InetSocketAddress startServer(ServerSessionFrameListener listener) throws Exception
    {
        server = new Server();
        SPDYServerConnector serverConnector = new SPDYServerConnector(server, listener);
        serverConnector.addConnectionFactory(new SPDYServerConnectionFactory(version, listener));
        serverConnector.setPort(0);
        server.addConnector(serverConnector);
        server.start();
        return new InetSocketAddress("localhost", serverConnector.getLocalPort());
    }

    protected InetSocketAddress startProxy(InetSocketAddress address) throws Exception
    {
        proxy = new Server();
        ProxyEngineSelector proxyEngineSelector = new ProxyEngineSelector();
        SPDYProxyEngine spdyProxyEngine = new SPDYProxyEngine(factory);
        proxyEngineSelector.putProxyEngine("spdy/" + version, spdyProxyEngine);
        proxyEngineSelector.putProxyServerInfo("localhost", new ProxyEngineSelector.ProxyServerInfo("spdy/" + version, address.getHostName(), address.getPort()));
        proxyConnector = new HTTPSPDYProxyServerConnector(proxy, proxyEngineSelector);
        proxyConnector.setPort(9999);
        proxy.addConnector(proxyConnector);
        proxy.start();
        return new InetSocketAddress("localhost", proxyConnector.getLocalPort());
    }

    @Before
    public void init() throws Exception
    {
        factory = new SPDYClient.Factory();
        factory.start();
        httpClient = new HttpClient();
        httpClient.start();
        httpClient2 = new HttpClient();
        httpClient2.start();
    }

    @After
    public void destroy() throws Exception
    {
        httpClient.stop();
        httpClient2.stop();
        if (server != null)
        {
            server.stop();
            server.join();
        }
        if (proxy != null)
        {
            proxy.stop();
            proxy.join();
        }
        factory.stop();
    }

    @Test
    public void testClosingClientDoesNotCloseServer() throws Exception
    {
        final CountDownLatch closeLatch = new CountDownLatch(1);
        InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
        {
            @Override
            public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
            {
                Fields responseHeaders = new Fields();
                responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
                responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
                stream.reply(new ReplyInfo(responseHeaders, true), new Callback.Adapter());
                return null;
            }

            @Override
            public void onGoAway(Session session, GoAwayResultInfo goAwayInfo)
            {
                closeLatch.countDown();
            }
        }));

        Request request = httpClient.newRequest("localhost", proxyAddress.getPort()).method("GET");
        request.header("Connection", "close");
        ContentResponse response = request.send();

        assertThat("response status is 200 OK", response.getStatus(), is(200));

        // Must not close, other clients may still be connected
        Assert.assertFalse(closeLatch.await(1, TimeUnit.SECONDS));
    }

    @Test
    public void testGETThenNoContentFromTwoClients() throws Exception
    {
        InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
        {
            @Override
            public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
            {
                Assert.assertTrue(synInfo.isClose());
                Fields requestHeaders = synInfo.getHeaders();
                Assert.assertNotNull(requestHeaders.get("via"));

                Fields responseHeaders = new Fields();
                responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
                responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
                ReplyInfo replyInfo = new ReplyInfo(responseHeaders, true);
                stream.reply(replyInfo, new Callback.Adapter());
                return null;
            }
        }));

        ContentResponse response = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.GET)
                .send();
        assertThat("response code is 200 OK", response.getStatus(), is(200));

        // Perform another request with another client
        ContentResponse response2 = httpClient2.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.GET)
                .send();
        assertThat("response2 code is 200 OK", response2.getStatus(), is(200));
    }

    @Test
    public void testHEADRequest() throws Exception
    {
        InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
        {
            @Override
            public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
            {
                Assert.assertTrue(synInfo.isClose());
                Fields requestHeaders = synInfo.getHeaders();
                Assert.assertNotNull(requestHeaders.get("via"));

                Fields responseHeaders = new Fields();
                responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
                responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
                ReplyInfo replyInfo = new ReplyInfo(responseHeaders, true);
                stream.reply(replyInfo, new Callback.Adapter());

                return null;
            }
        }));
        ContentResponse response = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.HEAD).send();
        assertThat("response code is 200 OK", response.getStatus(), is(200));
    }

    @Test
    public void testGETThenSmallResponseContent() throws Exception
    {
        final byte[] data = "0123456789ABCDEF".getBytes(StandardCharsets.UTF_8);
        InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
        {
            @Override
            public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
            {
                Assert.assertTrue(synInfo.isClose());
                Fields requestHeaders = synInfo.getHeaders();
                Assert.assertNotNull(requestHeaders.get("via"));

                Fields responseHeaders = new Fields();
                responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
                responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
                responseHeaders.put("content-length", String.valueOf(data.length));

                ReplyInfo replyInfo = new ReplyInfo(responseHeaders, false);
                stream.reply(replyInfo, new Callback.Adapter());
                stream.data(new BytesDataInfo(data, true), new Callback.Adapter());

                return null;
            }
        }));

        ContentResponse response = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.GET)
                .send();
        assertThat("response code is 200 OK", response.getStatus(), is(200));
        assertThat(Arrays.equals(response.getContent(), data), is(true));

        // Perform another request so that we are sure we reset the states of parsers and generators
        ContentResponse response2 = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.GET)
                .send();
        assertThat("response2 code is 200 OK", response2.getStatus(), is(200));
        assertThat(Arrays.equals(response2.getContent(), data), is(true));
    }

    @Test
    public void testPOSTWithSmallRequestContentThenRedirect() throws Exception
    {
        final String data = "0123456789ABCDEF";
        InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
        {
            @Override
            public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
            {
                return new StreamFrameListener.Adapter()
                {
                    @Override
                    public void onData(Stream stream, DataInfo dataInfo)
                    {
                        dataInfo.consume(dataInfo.length());
                        if (dataInfo.isClose())
                        {
                            Fields headers = new Fields();
                            headers.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
                            headers.put(HTTPSPDYHeader.STATUS.name(version), "303 See Other");
                            headers.put(HttpHeader.LOCATION.asString(),"http://other.location");
                            stream.reply(new ReplyInfo(headers, true), new Callback.Adapter());
                        }
                    }
                };
            }
        }));

        ContentResponse response = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.POST).content(new
                StringContentProvider(data)).followRedirects(false).send();
        assertThat("response code is 303", response.getStatus(), is(303));

        // Perform another request so that we are sure we reset the states of parsers and generators
        ContentResponse response2 = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod
                .POST).content(new StringContentProvider(data)).followRedirects(false).send();
        assertThat("response2 code is 303", response2.getStatus(), is(303));
    }

    @Test
    public void testPOSTWithSmallRequestContentThenSmallResponseContent() throws Exception
    {
        String dataString = "0123456789ABCDEF";
        final byte[] data = dataString.getBytes(StandardCharsets.UTF_8);
        InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
        {
            @Override
            public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
            {
                return new StreamFrameListener.Adapter()
                {
                    @Override
                    public void onData(Stream stream, DataInfo dataInfo)
                    {
                        dataInfo.consume(dataInfo.length());
                        if (dataInfo.isClose())
                        {
                            Fields responseHeaders = new Fields();
                            responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
                            responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");
                            responseHeaders.put("content-length", String.valueOf(data.length));
                            ReplyInfo replyInfo = new ReplyInfo(responseHeaders, false);
                            stream.reply(replyInfo, new Callback.Adapter());
                            stream.data(new BytesDataInfo(data, true), new Callback.Adapter());
                        }
                    }
                };
            }
        }));

        ContentResponse response = httpClient.POST("http://localhost:" + proxyAddress.getPort() + "/").content(new
                StringContentProvider(dataString)).send();
        assertThat("response status is 200 OK", response.getStatus(), is(200));
        assertThat("response content matches expected dataString", response.getContentAsString(), is(dataString));

        // Perform another request so that we are sure we reset the states of parsers and generators
        response = httpClient.POST("http://localhost:" + proxyAddress.getPort() + "/").content(new
                StringContentProvider(dataString)).send();
        assertThat("response status is 200 OK", response.getStatus(), is(200));
        assertThat("response content matches expected dataString", response.getContentAsString(), is(dataString));
    }

    @Test
    public void testGETThenSPDYPushIsIgnored() throws Exception
    {
        final byte[] data = "0123456789ABCDEF".getBytes(StandardCharsets.UTF_8);
        InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
        {
            @Override
            public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
            {
                Fields responseHeaders = new Fields();
                responseHeaders.put(HTTPSPDYHeader.VERSION.name(version), "HTTP/1.1");
                responseHeaders.put(HTTPSPDYHeader.STATUS.name(version), "200 OK");

                Fields pushHeaders = new Fields();
                pushHeaders.put(HTTPSPDYHeader.URI.name(version), "/push");
                stream.push(new PushInfo(5, TimeUnit.SECONDS, pushHeaders, false), new Promise.Adapter<Stream>()
                {
                    @Override
                    public void succeeded(Stream pushStream)
                    {
                        pushStream.data(new BytesDataInfo(data, true), new Callback.Adapter());
                    }
                });

                stream.reply(new ReplyInfo(responseHeaders, true), new Callback.Adapter());
                return null;
            }
        }));

        ContentResponse response = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.GET).send();
        assertThat("response code is 200 OK", response.getStatus(), is(200));
    }

    @Test
    public void testGETThenReset() throws Exception
    {
        InetSocketAddress proxyAddress = startProxy(startServer(new ServerSessionFrameListener.Adapter()
        {
            @Override
            public StreamFrameListener onSyn(Stream stream, SynInfo synInfo)
            {
                Assert.assertTrue(synInfo.isClose());
                Fields requestHeaders = synInfo.getHeaders();
                Assert.assertNotNull(requestHeaders.get("via"));

                stream.getSession().rst(new RstInfo(stream.getId(), StreamStatus.REFUSED_STREAM), new Callback.Adapter());

                return null;
            }
        }));

        ContentResponse response = httpClient.newRequest("localhost", proxyAddress.getPort()).method(HttpMethod.GET).send();
        assertThat("response code is 502 Gateway Error", response.getStatus(), is(502));
    }
}
