/*******************************************************************************
 * Copyright (c) 2007, 2016 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Google Inc - add support for accepting multiple connections
 *******************************************************************************/
package org.eclipse.jdt.internal.launching;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.IStreamsProxy;
import org.eclipse.jdi.TimeoutException;
import org.eclipse.jdt.debug.core.JDIDebugModel;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.osgi.util.NLS;

import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.connect.Connector;
import com.sun.jdi.connect.IllegalConnectorArgumentsException;
import com.sun.jdi.connect.ListeningConnector;
import com.sun.jdi.connect.TransportTimeoutException;

/**
 * A process that represents a VM listening connector that is waiting for some VM(s) to remotely connect. Allows the user to see the status of the
 * connection and terminate it. If a successful connection occurs, the debug target is added to the launch and, if a configured number of connections
 * have been reached, then this process is removed.
 *
 * @since 3.4
 * @see SocketListenConnector
 */
public class SocketListenConnectorProcess implements IProcess {
	/**
	 * Whether this process has been terminated.
	 */
	private boolean fTerminated = false;
	/**
	 * The launch this process belongs to
	 */
	private ILaunch fLaunch;
	/**
	 * The port this connector will listen on.
	 */
	private String fPort;
	/**
	 * The number of incoming connections to accept (0 = unlimited). Setting to 1 mimics previous behaviour.
	 */
	private int fConnectionLimit;
	/** The number of connections accepted so far. */
	private int fAccepted = 0;
	/**
	 * The system job that will wait for incoming VM connections.
	 */
	private WaitForConnectionJob fWaitForConnectionJob;

	/** Time when this instance was created (milliseconds) */
	private long fStartTime;

	/**
	 * Creates this process.  The label for this process will state
	 * the port the connector is listening at.
	 * @param launch the launch this process belongs to
	 * @param port the port the connector will wait on
	 * @param connectionLimit the number of incoming connections to accept (0 = unlimited)
	 */
	public SocketListenConnectorProcess(ILaunch launch, String port, int connectionLimit){
		fLaunch = launch;
		fPort = port;
		fConnectionLimit = connectionLimit;
	}

	/**
	 * Starts a job that will accept a VM remotely connecting to the
	 * given connector.  The #startListening() method must have been
	 * called on the connector with the same arguments before calling
	 * this method.  The 'port' argument in the map should have the same
	 * value as the port specified in this process' constructor.
	 *
	 * @param connector the connector that will accept incoming connections
	 * @param arguments map of arguments that are used by the connector
	 * @throws CoreException if a problem occurs trying to accept a connection
	 * @see SocketListenConnector
	 */
	public void waitForConnection(ListeningConnector connector, Map<String, Connector.Argument> arguments) throws CoreException{
		if (isTerminated()){
			throw new CoreException(getStatus(LaunchingMessages.SocketListenConnectorProcess_0, null, IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED));
		}
		fStartTime = System.currentTimeMillis();
		fAccepted = 0;
		// If the connector does not support multiple connections, accept a single connection
		if (!connector.supportsMultipleConnections()) {
			fConnectionLimit = 1;
		}

		fLaunch.addProcess(this);
		fWaitForConnectionJob = new WaitForConnectionJob(connector,arguments);
		fWaitForConnectionJob.setPriority(Job.SHORT);
		fWaitForConnectionJob.setSystem(true);
		fWaitForConnectionJob.addJobChangeListener(new JobChangeAdapter(){
			@Override
			public void running(IJobChangeEvent event) {
				fireReadyToAcceptEvent();
			}
			@Override
			public void done(IJobChangeEvent event) {
				if (event.getResult().isOK() && continueListening()) {
					fWaitForConnectionJob.schedule();
				} else {
					try{
						terminate();
					} catch (DebugException e){}
				}
			}
		});
		fWaitForConnectionJob.schedule();
	}

	/**
	 * Return true if this connector should continue listening for further connections.
	 */
	protected boolean continueListening() {
		return !isTerminated() && (fWaitForConnectionJob != null && !fWaitForConnectionJob.fListeningStopped)
				&& (fConnectionLimit <= 0 || fConnectionLimit - fAccepted > 0);
	}

	/**
	 * Returns an error status using the passed parameters.
	 *
	 * @param message the status message
	 * @param exception lower level exception associated with the
	 *  error, or <code>null</code> if none
	 * @param code error code
	 * @return the new {@link IStatus}
	 */
	protected static IStatus getStatus(String message, Throwable exception, int code) {
		return new Status(IStatus.ERROR, LaunchingPlugin.getUniqueIdentifier(), code, message, exception);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IProcess#getExitValue()
	 */
	@Override
	public int getExitValue() throws DebugException {
		return 0;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IProcess#getLabel()
	 */
	@Override
	public String getLabel() {
		return NLS.bind(LaunchingMessages.SocketListenConnectorProcess_1, new String[]{fPort});
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IProcess#getLaunch()
	 */
	@Override
	public ILaunch getLaunch() {
		return fLaunch;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
	 */
	@Override
	public boolean canTerminate() {
		return !fTerminated;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
	 */
	@Override
	public boolean isTerminated() {
		return fTerminated;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ITerminate#terminate()
	 */
	@Override
	public void terminate() throws DebugException {
		if (!fTerminated){
			fTerminated = true;
			fLaunch.removeProcess(this);
			if (fWaitForConnectionJob != null){
				fWaitForConnectionJob.cancel();
				fWaitForConnectionJob.stopListening();
				fWaitForConnectionJob = null;
			}
			fireTerminateEvent();
		}
	}

	/**
	 * Fires a terminate event.
	 */
	protected void fireTerminateEvent() {
		DebugPlugin manager= DebugPlugin.getDefault();
		if (manager != null) {
			manager.fireDebugEventSet(new DebugEvent[]{new DebugEvent(this, DebugEvent.TERMINATE)});
		}
	}

	/**
	 * Fires a custom model specific event when this connector is ready to accept incoming
	 * connections from a remote VM.
	 */
	protected void fireReadyToAcceptEvent(){
		DebugPlugin manager= DebugPlugin.getDefault();
		if (manager != null) {
			manager.fireDebugEventSet(new DebugEvent[]{new DebugEvent(this, DebugEvent.MODEL_SPECIFIC, IJavaLaunchConfigurationConstants.DETAIL_CONFIG_READY_TO_ACCEPT_REMOTE_VM_CONNECTION)});
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IProcess#getStreamsProxy()
	 */
	@Override
	public IStreamsProxy getStreamsProxy() {
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IProcess#getAttribute(java.lang.String)
	 */
	@Override
	public String getAttribute(String key) {
		return null;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IProcess#setAttribute(java.lang.String, java.lang.String)
	 */
	@Override
	public void setAttribute(String key, String value) {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	@Override
	public <T> T getAdapter(Class<T> adapter) {
		return null;
	}

	/**
	 * Return the time since this connector was started.
	 */
	private String getRunningTime() {
		long total = System.currentTimeMillis() - fStartTime;
		StringWriter result = new StringWriter();
		PrintWriter writer = new PrintWriter(result);
		int minutes = (int) (total / 60 / 1000);
		int seconds = (int) (total / 1000) % 60;
		int milliseconds = (int) (total / 1000) % 1000;
		writer.printf("%02d:%02d.%03d", minutes, seconds, milliseconds).close(); //$NON-NLS-1$
		return result.toString();
	}

	/**
	 * Job that waits for incoming VM connections. When a remote VM connection is accepted, a debug target is created.
	 */
	class WaitForConnectionJob extends Job{

		private ListeningConnector fConnector;
		private Map<String, Connector.Argument> fArguments;
		/**
		 * Flag that can be set to tell this job that waiting
		 * for incoming connections has been cancelled.  If true,
		 * IOExceptions will be ignored, allowing other threads
		 * to close the socket without generating an error.
		 */
		private boolean fListeningStopped = false;

		public WaitForConnectionJob(ListeningConnector connector, Map<String, Connector.Argument> arguments) {
			super(getLabel());
			fConnector = connector;
			fArguments = arguments;
		}

		@Override
		protected IStatus run(IProgressMonitor monitor) {
			try{
				// The following code sets a timeout (not officially supported in Sun's spec).
				// Allows polling for job cancellation. If the implementation does not support timeout
				// the job cannot be cancelled (but the launch can still be terminated).
				Connector.Argument timeout = fArguments.get("timeout"); //$NON-NLS-1$
				if (timeout != null){
					timeout.setValue("3000"); //$NON-NLS-1$
				}

				VirtualMachine vm = null;
				while (vm == null && !monitor.isCanceled()){
					try {
						vm = fConnector.accept(fArguments);
					} catch (TransportTimeoutException e){
					}
				}

				if (monitor.isCanceled()){
					fConnector.stopListening(fArguments);
					return Status.CANCEL_STATUS;
				}

				ILaunchConfiguration configuration = fLaunch.getLaunchConfiguration();
				boolean allowTerminate = false;
				if (configuration != null) {
					try{
						allowTerminate = configuration.getAttribute(IJavaLaunchConfigurationConstants.ATTR_ALLOW_TERMINATE, false);
					} catch (CoreException e) {
						LaunchingPlugin.log(e);
					}
				}
				Connector.Argument portArg= fArguments.get("port"); //$NON-NLS-1$
				String vmLabel = constructVMLabel(vm, portArg.value(), fLaunch.getLaunchConfiguration());
				IDebugTarget debugTarget= JDIDebugModel.newDebugTarget(fLaunch, vm, vmLabel, null, allowTerminate, true);
				fLaunch.addDebugTarget(debugTarget);
				fAccepted++;
				return Status.OK_STATUS;
			} catch (IOException e) {
				if (fListeningStopped){
					return Status.CANCEL_STATUS;
				}
				return getStatus(LaunchingMessages.SocketListenConnectorProcess_4, e, IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED);
			} catch (IllegalConnectorArgumentsException e) {
				return getStatus(LaunchingMessages.SocketListenConnectorProcess_4, e, IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED);
			}
		}

		/* (non-Javadoc)
		 * @see org.eclipse.core.runtime.jobs.Job#canceling()
		 */
		@Override
		protected void canceling() {
			stopListening();
		}

		/**
		 * Tells the listening connector to stop listening.  Ensures
		 * that the socket is closed and the port released.  Sets a flag
		 * so that the IOException thrown by the connector's accept method
		 * will be ignored.
		 */
		protected void stopListening() {
			if (!fListeningStopped){
				try{
					fListeningStopped = true;
					fConnector.stopListening(fArguments);
				} catch (IOException e) {
					done(getStatus(LaunchingMessages.SocketListenConnectorProcess_5, e, IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED));
				} catch (IllegalConnectorArgumentsException e) {
					done(getStatus(LaunchingMessages.SocketListenConnectorProcess_5, e, IJavaLaunchConfigurationConstants.ERR_REMOTE_VM_CONNECTION_FAILED));
				}
			}
		}

		/**
		 * Helper method that constructs a human-readable label for a remote VM.
		 * @param vm the VM
		 * @param port the port
		 * @param configuration the configuration
		 * @return the new VM label
		 */
		protected String constructVMLabel(VirtualMachine vm, String port, ILaunchConfiguration configuration) {
			String name = null;
			try {
				name = vm.name();
			} catch (TimeoutException e) {
				// do nothing
			} catch (VMDisconnectedException e) {
				// do nothing
			}
			if (name == null) {
				if (configuration == null) {
					name = ""; //$NON-NLS-1$
				} else {
					name = configuration.getName();
				}
			}
			StringBuilder buffer = new StringBuilder(name);
			if (fConnectionLimit != 1) {
				// if we're accepting multiple incoming connections,
				// append the time when each connection was accepted
				buffer.append('<').append(getRunningTime()).append('>');
			}
			buffer.append('[');
			buffer.append(port);
			buffer.append(']');
			return buffer.toString();
		}

	}
}
