/*
 * Copyright (c) 2008-2012, 2015 Eike Stepper (Berlin, Germany) and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Eike Stepper - initial API and implementation
 *    Teerawat Chaiyakijpichet (No Magic Asia Ltd.) - SSL
 */
package org.eclipse.net4j.tests;

import org.eclipse.net4j.Net4jUtil;
import org.eclipse.net4j.buffer.IBufferPool;
import org.eclipse.net4j.channel.IChannel;
import org.eclipse.net4j.connector.ConnectorException;
import org.eclipse.net4j.connector.IConnector;
import org.eclipse.net4j.internal.tcp.TCPAcceptor;
import org.eclipse.net4j.internal.tcp.TCPAcceptorFactory;
import org.eclipse.net4j.internal.tcp.TCPClientConnector;
import org.eclipse.net4j.internal.tcp.TCPConnector;
import org.eclipse.net4j.internal.tcp.TCPConnectorFactory;
import org.eclipse.net4j.internal.tcp.TCPSelector;
import org.eclipse.net4j.internal.tcp.ssl.SSLAcceptor;
import org.eclipse.net4j.internal.tcp.ssl.SSLAcceptorFactory;
import org.eclipse.net4j.internal.tcp.ssl.SSLClientConnector;
import org.eclipse.net4j.internal.tcp.ssl.SSLConnectorFactory;
import org.eclipse.net4j.tcp.ITCPSelector;
import org.eclipse.net4j.tcp.TCPUtil;
import org.eclipse.net4j.tests.bundle.OM;
import org.eclipse.net4j.util.collection.RoundRobinBlockingQueue;
import org.eclipse.net4j.util.concurrent.ConcurrencyUtil;
import org.eclipse.net4j.util.concurrent.ThreadPool;
import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.net4j.util.lifecycle.LifecycleUtil;
import org.eclipse.net4j.util.security.ChallengeNegotiator;
import org.eclipse.net4j.util.security.NegotiationException;
import org.eclipse.net4j.util.security.PasswordCredentials;
import org.eclipse.net4j.util.security.PasswordCredentialsProvider;
import org.eclipse.net4j.util.security.Randomizer;
import org.eclipse.net4j.util.security.ResponseNegotiator;
import org.eclipse.net4j.util.security.UserManager;

import org.eclipse.spi.net4j.Channel;
import org.eclipse.spi.net4j.InternalChannel;

import java.nio.channels.ServerSocketChannel;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;

/**
 * @author Eike Stepper
 * @author Teerawat Chaiyakijpichet (No Magic Asia Ltd.)
 */
public class TCPConnectorTest extends AbstractTransportTest
{
  private static final int TIMEOUT = 10000;

  private static final int PORT = 2040;

  private static final String USER_ID = "stepper"; //$NON-NLS-1$

  private static final String INVALID_USER_ID = "invalid"; //$NON-NLS-1$

  private static final char[] PASSWORD = "eike2008".toCharArray(); //$NON-NLS-1$

  private static final char[] INVALID_PASSWORD = "invalid".toCharArray(); //$NON-NLS-1$

  private static final PasswordCredentials CREDENTIALS = new PasswordCredentials(USER_ID, PASSWORD);

  private ExecutorService threadPool;

  private IBufferPool bufferPool;

  private TCPSelector selector;

  private TCPAcceptor acceptor;

  private TCPConnector connector;

  private Randomizer randomizer;

  private UserManager userManager;

  private ChallengeNegotiator challengeNegotiator;

  private PasswordCredentialsProvider credentialsProvider;

  private ResponseNegotiator responseNegotiator;

  @Override
  protected void doTearDown() throws Exception
  {
    cleanup();
    super.doTearDown();
  }

  private void cleanup() throws Exception
  {
    sleep(100);

    if (connector != null)
    {
      connector.close();
      connector = null;
    }

    if (responseNegotiator != null)
    {
      LifecycleUtil.deactivate(responseNegotiator);
      responseNegotiator = null;
    }

    if (credentialsProvider != null)
    {
      LifecycleUtil.deactivate(credentialsProvider);
      credentialsProvider = null;
    }

    if (acceptor != null)
    {
      acceptor.close();
      acceptor = null;
    }

    if (challengeNegotiator != null)
    {
      LifecycleUtil.deactivate(challengeNegotiator);
      challengeNegotiator = null;
    }

    if (userManager != null)
    {
      LifecycleUtil.deactivate(userManager);
      userManager = null;
    }

    if (randomizer != null)
    {
      LifecycleUtil.deactivate(randomizer);
      randomizer = null;
    }

    if (selector != null)
    {
      LifecycleUtil.deactivate(selector);
      selector = null;
    }

    if (bufferPool != null)
    {
      LifecycleUtil.deactivate(bufferPool);
      bufferPool = null;
    }

    if (threadPool != null)
    {
      LifecycleUtil.deactivate(threadPool);
      threadPool = null;
    }
  }

  private void provideTransport()
  {
    selector = new TCPSelector();

    if (useSSLTransport())
    {
      acceptor = new SSLAcceptor();
      container.putElement(SSLAcceptorFactory.PRODUCT_GROUP, SSLAcceptorFactory.TYPE, null, acceptor);

      // cannot use same container with the acceptor.
      connector = new SSLClientConnector();
      separateContainer.putElement(SSLConnectorFactory.PRODUCT_GROUP, SSLConnectorFactory.TYPE, null, acceptor);
    }
    else
    {
      acceptor = new TCPAcceptor();
      container.putElement(TCPAcceptorFactory.PRODUCT_GROUP, TCPUtil.FACTORY_TYPE, null, acceptor);

      connector = new TCPClientConnector();
      container.putElement(TCPConnectorFactory.PRODUCT_GROUP, TCPConnectorFactory.TYPE, null, acceptor);
    }
  }

  private void provideTransport(final long increaseDelayAcceptor)
  {
    selector = new TCPSelector();

    if (useSSLTransport())
    {
      acceptor = new SSLAcceptor()
      {
        @Override
        public void handleAccept(ITCPSelector selector, ServerSocketChannel serverSocketChannel)
        {
          ConcurrencyUtil.sleep(increaseDelayAcceptor);
          super.handleAccept(selector, serverSocketChannel);
        }
      };

      connector = new SSLClientConnector();
    }
    else
    {
      acceptor = new TCPAcceptor()
      {
        @Override
        public void handleAccept(ITCPSelector selector, ServerSocketChannel serverSocketChannel)
        {
          ConcurrencyUtil.sleep(increaseDelayAcceptor);
          super.handleAccept(selector, serverSocketChannel);
        }
      };

      connector = new TCPClientConnector();
    }
  }

  public void testDeferredActivation() throws Exception
  {
    final long DELAY = 500L;
    threadPool = ThreadPool.create();
    bufferPool = Net4jUtil.createBufferPool();
    LifecycleUtil.activate(bufferPool);

    provideTransport(DELAY);

    selector.activate();

    acceptor.setStartSynchronously(true);
    acceptor.setSynchronousStartTimeout(TIMEOUT);
    acceptor.getConfig().setBufferProvider(bufferPool);
    acceptor.getConfig().setReceiveExecutor(threadPool);
    acceptor.setSelector(selector);
    acceptor.setAddress("0.0.0.0"); //$NON-NLS-1$
    acceptor.setPort(PORT);
    acceptor.activate();

    connector.getConfig().setBufferProvider(bufferPool);
    connector.getConfig().setReceiveExecutor(threadPool);
    connector.setSelector(selector);
    connector.setHost("localhost"); //$NON-NLS-1$
    connector.setPort(PORT);
    connector.activate();
    // Can fail due to timing variations: assertEquals(false, connector.isActive());

    connector.waitForConnection(DEFAULT_TIMEOUT);
    assertEquals(true, connector.isActive());
  }

  public void testDeferredActivation10() throws Exception
  {
    for (int i = 0; i < 10; i++)
    {
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      IOUtil.OUT().println("#####################################################"); //$NON-NLS-1$
      IOUtil.OUT().println(" RUN = " + i); //$NON-NLS-1$
      IOUtil.OUT().println("#####################################################"); //$NON-NLS-1$
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      testDeferredActivation();
      cleanup();
    }
  }

  public void testNegotiationSuccess() throws Exception
  {
    threadPool = ThreadPool.create();
    bufferPool = Net4jUtil.createBufferPool();
    LifecycleUtil.activate(bufferPool);

    randomizer = new Randomizer();
    randomizer.activate();

    userManager = new UserManager();
    userManager.activate();
    userManager.addUser(USER_ID, PASSWORD);

    challengeNegotiator = new ChallengeNegotiator();
    challengeNegotiator.setRandomizer(randomizer);
    challengeNegotiator.setUserManager(userManager);
    challengeNegotiator.activate();

    provideTransport();

    selector.activate();

    acceptor.setStartSynchronously(true);
    acceptor.setSynchronousStartTimeout(TIMEOUT);
    acceptor.getConfig().setBufferProvider(bufferPool);
    acceptor.getConfig().setReceiveExecutor(threadPool);
    acceptor.getConfig().setNegotiator(challengeNegotiator);
    acceptor.setSelector(selector);
    acceptor.setAddress("0.0.0.0"); //$NON-NLS-1$
    acceptor.setPort(PORT);
    acceptor.activate();

    credentialsProvider = new PasswordCredentialsProvider(CREDENTIALS);
    LifecycleUtil.activate(credentialsProvider);

    responseNegotiator = new ResponseNegotiator();
    responseNegotiator.setCredentialsProvider(credentialsProvider);
    responseNegotiator.activate();

    connector.getConfig().setBufferProvider(bufferPool);
    connector.getConfig().setReceiveExecutor(threadPool);
    connector.getConfig().setNegotiator(responseNegotiator);
    connector.setSelector(selector);
    connector.setHost("localhost"); //$NON-NLS-1$
    connector.setPort(PORT);
    connector.activate();

    connector.waitForConnection(DEFAULT_TIMEOUT);

    InternalChannel clientChannel = connector.openChannel();
    assertEquals(USER_ID, clientChannel.getUserID());

    IConnector serverConnector = acceptor.getElements()[0];
    IChannel serverChannel = serverConnector.getElements()[0];
    assertEquals(USER_ID, serverChannel.getUserID());

    System.out.println(serverChannel);
  }

  public void testNegotiationSuccess10() throws Exception
  {
    for (int i = 0; i < 10; i++)
    {
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      IOUtil.OUT().println("#####################################################"); //$NON-NLS-1$
      IOUtil.OUT().println("                          RUN = " + i); //$NON-NLS-1$
      IOUtil.OUT().println("#####################################################"); //$NON-NLS-1$
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      IOUtil.OUT().println();
      testNegotiationSuccess();
      cleanup();
    }
  }

  public void testInvalidUser() throws Exception
  {
    threadPool = ThreadPool.create();
    bufferPool = Net4jUtil.createBufferPool();
    LifecycleUtil.activate(bufferPool);

    randomizer = new Randomizer();
    randomizer.activate();

    userManager = new UserManager();
    userManager.activate();
    userManager.addUser(INVALID_USER_ID, PASSWORD);

    challengeNegotiator = new ChallengeNegotiator();
    challengeNegotiator.setRandomizer(randomizer);
    challengeNegotiator.setUserManager(userManager);
    challengeNegotiator.activate();

    provideTransport();

    selector.activate();

    acceptor.setStartSynchronously(true);
    acceptor.setSynchronousStartTimeout(TIMEOUT);
    acceptor.getConfig().setBufferProvider(bufferPool);
    acceptor.getConfig().setReceiveExecutor(threadPool);
    acceptor.getConfig().setNegotiator(challengeNegotiator);
    acceptor.setSelector(selector);
    acceptor.setAddress("0.0.0.0"); //$NON-NLS-1$
    acceptor.setPort(PORT);
    acceptor.activate();

    credentialsProvider = new PasswordCredentialsProvider(CREDENTIALS);
    LifecycleUtil.activate(credentialsProvider);

    responseNegotiator = new ResponseNegotiator();
    responseNegotiator.setCredentialsProvider(credentialsProvider);
    responseNegotiator.activate();

    connector.getConfig().setBufferProvider(bufferPool);
    connector.getConfig().setReceiveExecutor(threadPool);
    connector.getConfig().setNegotiator(responseNegotiator);
    connector.setSelector(selector);
    connector.setHost("localhost"); //$NON-NLS-1$
    connector.setPort(PORT);

    try
    {
      connector.connectAsync();
      connector.waitForConnection(DEFAULT_TIMEOUT_EXPECTED);
      fail("ConnectorException expected"); //$NON-NLS-1$
    }
    catch (ConnectorException ex)
    {
      OM.LOG.info("Expected ConnectorException:", ex); //$NON-NLS-1$
      assertEquals(true, ex.getCause() instanceof NegotiationException);
    }
  }

  public void testInvalidPassword() throws Exception
  {
    threadPool = ThreadPool.create();
    bufferPool = Net4jUtil.createBufferPool();
    LifecycleUtil.activate(bufferPool);

    randomizer = new Randomizer();
    randomizer.activate();

    userManager = new UserManager();
    userManager.activate();
    userManager.addUser(USER_ID, INVALID_PASSWORD);

    challengeNegotiator = new ChallengeNegotiator();
    challengeNegotiator.setRandomizer(randomizer);
    challengeNegotiator.setUserManager(userManager);
    challengeNegotiator.activate();

    provideTransport();

    selector.activate();

    acceptor.setStartSynchronously(true);
    acceptor.setSynchronousStartTimeout(TIMEOUT);
    acceptor.getConfig().setBufferProvider(bufferPool);
    acceptor.getConfig().setReceiveExecutor(threadPool);
    acceptor.getConfig().setNegotiator(challengeNegotiator);
    acceptor.setSelector(selector);
    acceptor.setAddress("0.0.0.0"); //$NON-NLS-1$
    acceptor.setPort(PORT);
    acceptor.activate();

    credentialsProvider = new PasswordCredentialsProvider(CREDENTIALS);
    LifecycleUtil.activate(credentialsProvider);

    responseNegotiator = new ResponseNegotiator();
    responseNegotiator.setCredentialsProvider(credentialsProvider);
    responseNegotiator.activate();

    connector.getConfig().setBufferProvider(bufferPool);
    connector.getConfig().setReceiveExecutor(threadPool);
    connector.getConfig().setNegotiator(responseNegotiator);
    connector.setSelector(selector);
    connector.setHost("localhost"); //$NON-NLS-1$
    connector.setPort(PORT);

    try
    {
      connector.connectAsync();
      connector.waitForConnection(DEFAULT_TIMEOUT_EXPECTED);
      fail("ConnectorException expected"); //$NON-NLS-1$
    }
    catch (ConnectorException ex)
    {
      OM.LOG.info("Expected ConnectorException:", ex); //$NON-NLS-1$
      assertEquals(true, ex.getCause() instanceof NegotiationException);
    }
  }

  public void testNoNegotiator() throws Exception
  {
    threadPool = ThreadPool.create();
    bufferPool = Net4jUtil.createBufferPool();
    LifecycleUtil.activate(bufferPool);

    provideTransport();

    selector.activate();

    acceptor.setStartSynchronously(true);
    acceptor.setSynchronousStartTimeout(TIMEOUT);
    acceptor.getConfig().setBufferProvider(bufferPool);
    acceptor.getConfig().setReceiveExecutor(threadPool);
    acceptor.setSelector(selector);
    acceptor.setAddress("0.0.0.0"); //$NON-NLS-1$
    acceptor.setPort(PORT);
    acceptor.activate();

    connector.getConfig().setBufferProvider(bufferPool);
    connector.getConfig().setReceiveExecutor(threadPool);
    connector.setSelector(selector);
    connector.setHost("localhost"); //$NON-NLS-1$
    connector.setPort(PORT);
    connector.setUserID("SHOULD_FAIL_LATER"); //$NON-NLS-1$

    try
    {
      connector.connect();
      fail("ConnectorException expected"); //$NON-NLS-1$
    }
    catch (ConnectorException ex)
    {
      OM.LOG.info("Expected ConnectorException:", ex); //$NON-NLS-1$
      assertEquals(true, ex.getCause() instanceof IllegalStateException);
    }
  }

  public void testNegotiatorTooLate() throws Exception
  {
    threadPool = ThreadPool.create();
    bufferPool = Net4jUtil.createBufferPool();
    LifecycleUtil.activate(bufferPool);

    provideTransport();

    selector.activate();

    acceptor.setStartSynchronously(true);
    acceptor.setSynchronousStartTimeout(TIMEOUT);
    acceptor.getConfig().setBufferProvider(bufferPool);
    acceptor.getConfig().setReceiveExecutor(threadPool);
    acceptor.setSelector(selector);
    acceptor.setAddress("0.0.0.0"); //$NON-NLS-1$
    acceptor.setPort(PORT);
    acceptor.activate();

    connector.getConfig().setBufferProvider(bufferPool);
    connector.getConfig().setReceiveExecutor(threadPool);
    connector.setSelector(selector);
    connector.setHost("localhost"); //$NON-NLS-1$
    connector.setPort(PORT);
    connector.connect();

    credentialsProvider = new PasswordCredentialsProvider(CREDENTIALS);
    LifecycleUtil.activate(credentialsProvider);

    responseNegotiator = new ResponseNegotiator();
    responseNegotiator.setCredentialsProvider(credentialsProvider);
    responseNegotiator.activate();

    try
    {
      connector.getConfig().setNegotiator(responseNegotiator);
      fail("IllegalStateException expected"); //$NON-NLS-1$
    }
    catch (IllegalStateException ex)
    {
      OM.LOG.info("Expected IllegalStateException:", ex); //$NON-NLS-1$
    }
  }

  public void testRoundRobinBlockingQueue() throws Exception
  {
    BlockingQueue<IChannel> queue = new RoundRobinBlockingQueue<IChannel>();

    Channel[] channels = new Channel[3];

    for (int i = 0; i < channels.length; i++)
    {
      Channel c = new Channel();
      c.setID((short)i);
      channels[i] = c;
    }

    assertEquals(true, queue.isEmpty());
    assertNull(queue.peek());
    assertNull(queue.poll());

    // Order will be 0000...1111...2222...
    for (int i = 0; i < channels.length; i++)
    {
      for (int j = 0; j < 10; j++)
      {
        queue.put(channels[i]);
      }
    }

    for (int i = 0; i < 30; i++)
    {
      IChannel peek1 = queue.peek();
      IChannel peek2 = queue.peek();
      assertSame(peek1, peek2);

      IChannel poll = queue.poll();
      // The order should be 012012012012...
      assertEquals(i % 3, poll.getID());
      assertSame(peek1, poll);
    }

    assertEquals(true, queue.isEmpty());
    assertNull(queue.peek());
    assertNull(queue.poll());
  }

  /**
   * @author Teerawat Chaiyakijpichet (No Magic Asia Ltd.)
   */
  public static final class TCP extends TCPConnectorTest
  {
    @Override
    protected boolean useJVMTransport()
    {
      return false;
    }

    @Override
    protected boolean useSSLTransport()
    {
      return false;
    }
  }

  /**
   * @author Teerawat Chaiyakijpichet (No Magic Asia Ltd.)
   */
  public static final class SSL extends TCPConnectorTest
  {
    @Override
    protected boolean useJVMTransport()
    {
      return false;
    }

    @Override
    protected boolean useSSLTransport()
    {
      return true;
    }
  }
}
