/*******************************************************************************
 * Copyright (c) 2016 Google, Inc. 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:
 *     Google, Inc. - initial API and implementation
 *******************************************************************************/

package org.eclipse.jdt.debug.tests.connectors;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.jdt.debug.tests.AbstractDebugTest;
import org.eclipse.jdt.internal.launching.SocketListenConnector;
import org.eclipse.jdt.launching.SocketUtil;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.sun.jdi.connect.Connector;

/**
 * Test the SocketListenerConnector
 */
public class MultipleConnectionsTest extends AbstractDebugTest {

	public MultipleConnectionsTest(String name) {
		super(name);
	}

	private ILaunch launch = new MockLaunch();

	private SocketListenConnector connector;

	private int port;

	@Override
	@Before
	protected void setUp() throws Exception {
		super.setUp();
		port = SocketUtil.findFreePort();
	}

	@Test
	public void testDefaultSettings() throws CoreException {
		connector = new SocketListenConnector();
		Map<String, Connector.Argument> defaults = connector.getDefaultArguments();
		assertTrue(defaults.containsKey("connectionLimit"));
		assertEquals(1, ((Connector.IntegerArgument) defaults.get("connectionLimit")).intValue());
	}

	/**
	 * Ensure out-of-the-box settings mimics previous behaviour of accepting a
	 * single connection
	 *
	 * @throws IOException
	 */
	@Test
	public void testDefaultBehaviour() throws CoreException, InterruptedException {
		connector = new SocketListenConnector();
		Map<String, String> arguments = new HashMap<>();
		arguments.put("port", Integer.toString(port));
		connector.connect(arguments, new NullProgressMonitor(), launch);
		Thread.sleep(200);

		assertTrue("first connect should succeed", connect());
		assertFalse("second connect should fail", connect());
	}

	/**
	 * Ensure connector accepts a single connection
	 *
	 * @throws InterruptedException
	 */
	@Test
	public void testSingleConnectionBehaviour() throws CoreException, InterruptedException {
		connector = new SocketListenConnector();
		Map<String, String> arguments = new HashMap<>();
		arguments.put("port", Integer.toString(port));
		arguments.put("connectionLimit", "1");
		connector.connect(arguments, new NullProgressMonitor(), launch);
		Thread.sleep(200);

		assertTrue("first connect should succeed", connect());
		assertFalse("second connect should fail", connect());
	}

	/**
	 * Ensure out-of-the-box settings mimics previous behaviour of accepting a
	 * single connection
	 *
	 * @throws InterruptedException
	 */
	@Test
	public void testTwoConnectionsBehaviour() throws CoreException, InterruptedException {
		connector = new SocketListenConnector();
		Map<String, String> arguments = new HashMap<>();
		arguments.put("port", Integer.toString(port));
		arguments.put("connectionLimit", "2");
		connector.connect(arguments, new NullProgressMonitor(), launch);
		Thread.sleep(200);

		assertTrue("first connect should succeed", connect());
		assertTrue("second connect should succeed", connect());
	}

	/**
	 * Ensure out-of-the-box settings mimics previous behaviour of accepting a
	 * single connection
	 *
	 * @throws InterruptedException
	 */
	@Test
	public void testUnlimitedConnectionsBehaviour() throws CoreException, InterruptedException {
		connector = new SocketListenConnector();
		Map<String, String> arguments = new HashMap<>();
		arguments.put("port", Integer.toString(port));
		arguments.put("connectionLimit", "0");
		connector.connect(arguments, new NullProgressMonitor(), launch);
		Thread.sleep(200);

		for (int i = 0; i < 10; i++) {
			assertTrue("connection " + i + " should succeed", connect());
		}
	}

	@Override
	@After
	protected void tearDown() throws Exception {
		launch.terminate();
		super.tearDown();
	}

	private boolean connect() {
		boolean result = true;
		// Two try blocks to distinguish between exceptions from socket close (ignorable)
		// and from dealing with the remote (errors)
		try (Socket s = new Socket()) {
			try {
				s.connect(new InetSocketAddress(InetAddress.getLocalHost(), port));
				byte[] buffer = new byte[14];
				s.getInputStream().read(buffer);
				assertEquals("JDWP-Handshake", new String(buffer));
				s.getOutputStream().write("JDWP-Handshake".getBytes());
				s.getOutputStream().flush();
				// Closing gracelessly like this produces
				// com.sun.jdi.VMDisconnectedExceptions on the log. Could
				// respond to JDWP to try to bring down the connections
				// gracefully, but it's a bit involved.
			} catch (IOException e) {
				result = false;
			}
		} catch(IOException e) {
		}
		try {
			// sleep to allow the remote side to setup the connection
			Thread.sleep(1000);
		} catch (InterruptedException ex) {
			// ignore
		}
		return result;
	}
}
