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

import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;

import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketPolicy;
import org.eclipse.jetty.websocket.api.extensions.ExtensionConfig;
import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
import org.eclipse.jetty.websocket.client.WebSocketClient;
import org.eclipse.jetty.websocket.common.test.LeakTrackingBufferPoolRule;
import org.eclipse.jetty.websocket.common.util.Sha1Sum;
import org.eclipse.jetty.websocket.server.helper.CaptureSocket;
import org.eclipse.jetty.websocket.server.helper.EchoServlet;
import org.junit.After;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class PerMessageDeflateExtensionTest
{
    private static enum TestCaseMessageSize
    {
        TINY(10),
        SMALL(1024),
        MEDIUM(10*1024),
        LARGE(100*1024),
        HUGE(1024*1024);

        private int size;

        private TestCaseMessageSize(int size)
        {
            this.size = size;
        }
    }

    @Parameters(name = "{0} ({3}) (Input Buffer Size: {4} bytes)")
    public static List<Object[]> modes()
    {
        List<Object[]> modes = new ArrayList<>();

        for(TestCaseMessageSize size: TestCaseMessageSize.values())
        {
            modes.add(new Object[] { "Normal HTTP/WS", false, "ws", size, -1 });
            modes.add(new Object[] { "Encrypted HTTPS/WSS", true, "wss", size, -1 });
            int altInputBufSize = 15*1024;
            modes.add(new Object[] { "Normal HTTP/WS", false, "ws", size, altInputBufSize });
            modes.add(new Object[] { "Encrypted HTTPS/WSS", true, "wss", size, altInputBufSize });
        }

        return modes;
    }

    @Rule
    public LeakTrackingBufferPoolRule bufferPool = new LeakTrackingBufferPoolRule("Test");

    private SimpleServletServer server;
    private String scheme;
    private int msgSize;
    private int inputBufferSize;

    public PerMessageDeflateExtensionTest(String mode, boolean sslMode, String scheme, TestCaseMessageSize msgSize, int bufferSize) throws Exception
    {
        server = new SimpleServletServer(new EchoServlet());
        server.enableSsl(sslMode);
        server.start();

        this.scheme = scheme;
        this.msgSize = msgSize.size;
        this.inputBufferSize = bufferSize;
    }

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

    /**
     * Default configuration for permessage-deflate
     * @throws Exception on test failure
     */
    @Test
    public void testPerMessageDeflateDefault() throws Exception
    {
        Assume.assumeTrue("Server has permessage-deflate registered",
                server.getWebSocketServletFactory().getExtensionFactory().isAvailable("permessage-deflate"));

        Assert.assertThat("server scheme",server.getServerUri().getScheme(),is(scheme));

        int binBufferSize = (int) (msgSize * 1.5);

        WebSocketPolicy serverPolicy = server.getWebSocketServletFactory().getPolicy();

        // Ensure binBufferSize is sane (not smaller then other buffers)
        binBufferSize = Math.max(binBufferSize,serverPolicy.getMaxBinaryMessageSize());
        binBufferSize = Math.max(binBufferSize,serverPolicy.getMaxBinaryMessageBufferSize());
        binBufferSize = Math.max(binBufferSize,this.inputBufferSize);

        serverPolicy.setMaxBinaryMessageSize(binBufferSize);
        serverPolicy.setMaxBinaryMessageBufferSize(binBufferSize);

        WebSocketClient client = new WebSocketClient(server.getSslContextFactory(),null,bufferPool);
        WebSocketPolicy clientPolicy = client.getPolicy();
        clientPolicy.setMaxBinaryMessageSize(binBufferSize);
        clientPolicy.setMaxBinaryMessageBufferSize(binBufferSize);
        if (inputBufferSize > 0)
        {
            clientPolicy.setInputBufferSize(inputBufferSize);
        }

        try
        {
            client.start();
            // Make sure the read times out if there are problems with the implementation
            client.setMaxIdleTimeout(TimeUnit.SECONDS.toMillis(15));

            CaptureSocket clientSocket = new CaptureSocket();
            ClientUpgradeRequest request = new ClientUpgradeRequest();
            request.addExtensions("permessage-deflate");
            request.setSubProtocols("echo");

            Future<Session> fut = client.connect(clientSocket,server.getServerUri(),request);

            // Wait for connect
            Session session = fut.get(30,TimeUnit.SECONDS);

            assertThat("Response.extensions",getNegotiatedExtensionList(session),containsString("permessage-deflate"));

            // Create message
            byte msg[] = new byte[msgSize];
            Random rand = new Random();
            rand.setSeed(8080);
            rand.nextBytes(msg);

            // Calculate sha1
            String sha1 = Sha1Sum.calculate(msg);

            // Client sends first message
            session.getRemote().sendBytes(ByteBuffer.wrap(msg));

            clientSocket.messages.awaitEventCount(1,5,TimeUnit.SECONDS);
            String echoMsg = clientSocket.messages.poll();
            Assert.assertThat("Echo'd Message",echoMsg,is("binary[sha1="+sha1+"]"));
        }
        finally
        {
            client.stop();
        }
    }

    private String getNegotiatedExtensionList(Session session)
    {
        StringBuilder actual = new StringBuilder();
        actual.append('[');

        boolean delim = false;
        for (ExtensionConfig ext : session.getUpgradeResponse().getExtensions())
        {
            if (delim)
                actual.append(", ");
            actual.append(ext.getName());
            delim = true;
        }
        actual.append(']');

        return actual.toString();
    }
}
