//
//  ========================================================================
//  Copyright (c) 1995-2015 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.client;

import static org.hamcrest.Matchers.*;

import java.net.InetSocketAddress;
import java.net.URI;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

import org.eclipse.jetty.toolchain.test.AdvancedRunner;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.websocket.api.BatchMode;
import org.eclipse.jetty.websocket.api.RemoteEndpoint;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.UpgradeRequest;
import org.eclipse.jetty.websocket.api.annotations.WebSocket;
import org.eclipse.jetty.websocket.common.UpgradeRequestAdapter;
import org.eclipse.jetty.websocket.common.WebSocketSession;
import org.eclipse.jetty.websocket.common.frames.TextFrame;
import org.eclipse.jetty.websocket.common.io.FutureWriteCallback;
import org.eclipse.jetty.websocket.common.test.BlockheadServer;
import org.eclipse.jetty.websocket.common.test.IBlockheadServerConnection;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(AdvancedRunner.class)
public class WebSocketClientTest
{
    private BlockheadServer server;

    @Before
    public void startServer() throws Exception
    {
        server = new BlockheadServer();
        server.start();
    }

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

    @Test(expected = IllegalArgumentException.class)
    public void testAddExtension_NotInstalled() throws Exception
    {
        WebSocketClient client = new WebSocketClient();
        client.start();
        try
        {
            JettyTrackingSocket cliSock = new JettyTrackingSocket();

            client.getPolicy().setIdleTimeout(10000);

            URI wsUri = server.getWsUri();
            ClientUpgradeRequest request = new ClientUpgradeRequest();
            request.setSubProtocols("echo");
            request.addExtensions("x-bad");

            // Should trigger failure on bad extension
            client.connect(cliSock,wsUri,request);
        }
        finally
        {
            client.stop();
        }
    }

    @Test
    public void testBasicEcho_FromClient() throws Exception
    {
        WebSocketClient client = new WebSocketClient();
        client.start();
        try
        {
            JettyTrackingSocket cliSock = new JettyTrackingSocket();

            client.getPolicy().setIdleTimeout(10000);

            URI wsUri = server.getWsUri();
            ClientUpgradeRequest request = new ClientUpgradeRequest();
            request.setSubProtocols("echo");
            Future<Session> future = client.connect(cliSock,wsUri,request);

            final IBlockheadServerConnection srvSock = server.accept();
            srvSock.upgrade();

            Session sess = future.get(500,TimeUnit.MILLISECONDS);
            Assert.assertThat("Session",sess,notNullValue());
            Assert.assertThat("Session.open",sess.isOpen(),is(true));
            Assert.assertThat("Session.upgradeRequest",sess.getUpgradeRequest(),notNullValue());
            Assert.assertThat("Session.upgradeResponse",sess.getUpgradeResponse(),notNullValue());

            cliSock.assertWasOpened();
            cliSock.assertNotClosed();

            Collection<WebSocketSession> sessions = client.getBeans(WebSocketSession.class);
            Assert.assertThat("client.connectionManager.sessions.size",sessions.size(),is(1));

            RemoteEndpoint remote = cliSock.getSession().getRemote();
            remote.sendStringByFuture("Hello World!");
            if (remote.getBatchMode() == BatchMode.ON)
                remote.flush();
            srvSock.echoMessage(1,500,TimeUnit.MILLISECONDS);
            // wait for response from server
            cliSock.waitForMessage(500,TimeUnit.MILLISECONDS);

            cliSock.assertMessage("Hello World!");
        }
        finally
        {
            client.stop();
        }
    }

    @Test
    public void testBasicEcho_UsingCallback() throws Exception
    {
        WebSocketClient client = new WebSocketClient();
        client.setMaxIdleTimeout(160000);
        client.start();
        try
        {
            JettyTrackingSocket cliSock = new JettyTrackingSocket();

            URI wsUri = server.getWsUri();
            ClientUpgradeRequest request = new ClientUpgradeRequest();
            request.setSubProtocols("echo");
            Future<Session> future = client.connect(cliSock,wsUri,request);

            final IBlockheadServerConnection srvSock = server.accept();
            srvSock.upgrade();

            Session sess = future.get(500,TimeUnit.MILLISECONDS);
            Assert.assertThat("Session",sess,notNullValue());
            Assert.assertThat("Session.open",sess.isOpen(),is(true));
            Assert.assertThat("Session.upgradeRequest",sess.getUpgradeRequest(),notNullValue());
            Assert.assertThat("Session.upgradeResponse",sess.getUpgradeResponse(),notNullValue());

            cliSock.assertWasOpened();
            cliSock.assertNotClosed();

            Collection<WebSocketSession> sessions = client.getBeans(WebSocketSession.class);
            Assert.assertThat("client.connectionManager.sessions.size",sessions.size(),is(1));

            FutureWriteCallback callback = new FutureWriteCallback();

            cliSock.getSession().getRemote().sendString("Hello World!",callback);
            callback.get(1,TimeUnit.SECONDS);
        }
        finally
        {
            client.stop();
        }
    }

    @Test
    public void testBasicEcho_FromServer() throws Exception
    {
        WebSocketClient client = new WebSocketClient();
        client.start();
        try
        {
            JettyTrackingSocket wsocket = new JettyTrackingSocket();
            Future<Session> future = client.connect(wsocket,server.getWsUri());

            // Server
            final IBlockheadServerConnection srvSock = server.accept();
            srvSock.upgrade();

            // Validate connect
            Session sess = future.get(500,TimeUnit.MILLISECONDS);
            Assert.assertThat("Session",sess,notNullValue());
            Assert.assertThat("Session.open",sess.isOpen(),is(true));
            Assert.assertThat("Session.upgradeRequest",sess.getUpgradeRequest(),notNullValue());
            Assert.assertThat("Session.upgradeResponse",sess.getUpgradeResponse(),notNullValue());

            // Have server send initial message
            srvSock.write(new TextFrame().setPayload("Hello World"));

            // Verify connect
            future.get(500,TimeUnit.MILLISECONDS);
            wsocket.assertWasOpened();
            wsocket.awaitMessage(1,TimeUnit.SECONDS,2);

            wsocket.assertMessage("Hello World");
        }
        finally
        {
            client.stop();
        }
    }

    @Test
    public void testLocalRemoteAddress() throws Exception
    {
        WebSocketClient fact = new WebSocketClient();
        fact.start();
        try
        {
            JettyTrackingSocket wsocket = new JettyTrackingSocket();

            URI wsUri = server.getWsUri();
            Future<Session> future = fact.connect(wsocket,wsUri);

            IBlockheadServerConnection ssocket = server.accept();
            ssocket.upgrade();

            future.get(500,TimeUnit.MILLISECONDS);

            Assert.assertTrue(wsocket.openLatch.await(1,TimeUnit.SECONDS));

            InetSocketAddress local = wsocket.getSession().getLocalAddress();
            InetSocketAddress remote = wsocket.getSession().getRemoteAddress();

            Assert.assertThat("Local Socket Address",local,notNullValue());
            Assert.assertThat("Remote Socket Address",remote,notNullValue());

            // Hard to validate (in a portable unit test) the local address that was used/bound in the low level Jetty Endpoint
            Assert.assertThat("Local Socket Address / Host",local.getAddress().getHostAddress(),notNullValue());
            Assert.assertThat("Local Socket Address / Port",local.getPort(),greaterThan(0));

            Assert.assertThat("Remote Socket Address / Host",remote.getAddress().getHostAddress(),is(wsUri.getHost()));
            Assert.assertThat("Remote Socket Address / Port",remote.getPort(),greaterThan(0));
        }
        finally
        {
            fact.stop();
        }
    }

    @Test
    public void testMessageBiggerThanBufferSize() throws Exception
    {
        WebSocketClient factSmall = new WebSocketClient();
        factSmall.start();
        try
        {
            int bufferSize = 512;

            JettyTrackingSocket wsocket = new JettyTrackingSocket();

            URI wsUri = server.getWsUri();
            Future<Session> future = factSmall.connect(wsocket,wsUri);

            IBlockheadServerConnection ssocket = server.accept();
            ssocket.upgrade();

            future.get(500,TimeUnit.MILLISECONDS);

            Assert.assertTrue(wsocket.openLatch.await(1,TimeUnit.SECONDS));

            int length = bufferSize + (bufferSize / 2); // 1.5 times buffer size
            ssocket.write(0x80 | 0x01); // FIN + TEXT
            ssocket.write(0x7E); // No MASK and 2 bytes length
            ssocket.write(length >> 8); // first length byte
            ssocket.write(length & 0xFF); // second length byte
            for (int i = 0; i < length; ++i)
            {
                ssocket.write('x');
            }
            ssocket.flush();

            Assert.assertTrue(wsocket.dataLatch.await(1000,TimeUnit.SECONDS));
        }
        finally
        {
            factSmall.stop();
        }
    }

    /**
     * Ensure that <code>@WebSocket(maxTextMessageSize = 100*1024)</code> behaves as expected.
     * 
     * @throws Exception
     *             on test failure
     */
    @Test
    public void testMaxMessageSize() throws Exception
    {
        WebSocketClient client = new WebSocketClient();
        client.start();
        try
        {
            MaxMessageSocket wsocket = new MaxMessageSocket();

            URI wsUri = server.getWsUri();
            Future<Session> future = client.connect(wsocket,wsUri);

            IBlockheadServerConnection ssocket = server.accept();
            ssocket.upgrade();

            wsocket.awaitConnect(1,TimeUnit.SECONDS);

            Session sess = future.get(500,TimeUnit.MILLISECONDS);
            Assert.assertThat("Session",sess,notNullValue());
            Assert.assertThat("Session.open",sess.isOpen(),is(true));

            // Create string that is larger than default size of 64k
            // but smaller than maxMessageSize of 100k
            byte buf[] = new byte[80 * 1024];
            Arrays.fill(buf,(byte)'x');
            String msg = StringUtil.toUTF8String(buf,0,buf.length);

            wsocket.getSession().getRemote().sendStringByFuture(msg);
            ssocket.echoMessage(1,2,TimeUnit.SECONDS);
            // wait for response from server
            wsocket.waitForMessage(1,TimeUnit.SECONDS);

            wsocket.assertMessage(msg);

            Assert.assertTrue(wsocket.dataLatch.await(2,TimeUnit.SECONDS));
        }
        finally
        {
            client.stop();
        }
    }

    @Test
    public void testParameterMap() throws Exception
    {
        WebSocketClient fact = new WebSocketClient();
        fact.start();
        try
        {
            JettyTrackingSocket wsocket = new JettyTrackingSocket();

            URI wsUri = server.getWsUri().resolve("/test?snack=cashews&amount=handful&brand=off");
            Future<Session> future = fact.connect(wsocket,wsUri);

            IBlockheadServerConnection ssocket = server.accept();
            ssocket.upgrade();

            future.get(500,TimeUnit.MILLISECONDS);

            Assert.assertTrue(wsocket.openLatch.await(1,TimeUnit.SECONDS));

            Session session = wsocket.getSession();
            UpgradeRequest req = session.getUpgradeRequest();
            Assert.assertThat("Upgrade Request",req,notNullValue());

            Map<String, List<String>> parameterMap = req.getParameterMap();
            Assert.assertThat("Parameter Map",parameterMap,notNullValue());

            Assert.assertThat("Parameter[snack]",parameterMap.get("snack"),is(Arrays.asList(new String[]
            { "cashews" })));
            Assert.assertThat("Parameter[amount]",parameterMap.get("amount"),is(Arrays.asList(new String[]
            { "handful" })));
            Assert.assertThat("Parameter[brand]",parameterMap.get("brand"),is(Arrays.asList(new String[]
            { "off" })));

            Assert.assertThat("Parameter[cost]",parameterMap.get("cost"),nullValue());
        }
        finally
        {
            fact.stop();
        }
    }
}
