/*******************************************************************************
 * Copyright (c) 2000, 2018 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
 *     Pawel Piech - Bug 82003: The IDisconnect implementation by Launch module is too restrictive.
 *     Andrey Loskutov <loskutov@gmx.de> - Bug 506182 - Launch is not multi-thread safe
 *******************************************************************************/
package org.eclipse.debug.core;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IDisconnect;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.debug.internal.core.DebugCoreMessages;
import org.eclipse.debug.internal.core.LaunchManager;

/**
 * A launch is the result of launching a debug session
 * and/or one or more system processes. This class provides
 * a public implementation of <code>ILaunch</code> for client
 * use.
 * <p>
 * Clients may instantiate this class. Clients may subclass this class.
 * </p>
 * @see ILaunch
 * @see ILaunchManager
 */
public class Launch extends PlatformObject implements ILaunch, IDisconnect, ILaunchListener, ILaunchConfigurationListener, IDebugEventSetListener {

	/**
	 * Lock object for controlling access to processes and targets
	 */
	private final ReadWriteLock lock = new ReentrantReadWriteLock();

	private final Lock readLock = lock.readLock();

	private final Lock writeLock = lock.writeLock();

	/**
	 * The debug targets associated with this
	 * launch (the primary target is the first one
	 * in this collection), or empty if
	 * there are no debug targets.
	 */
	private List<IDebugTarget> fTargets = new ArrayList<>();

	/**
	 * The configuration that was launched, or null.
	 */
	private ILaunchConfiguration fConfiguration= null;

	/**
	 * The system processes associated with
	 * this launch, or empty if none.
	 */
	private List<IProcess> fProcesses = new ArrayList<>();

	/**
	 * The source locator to use in the debug session
	 * or <code>null</code> if not supported.
	 */
	private ISourceLocator fLocator= null;

	/**
	 * The mode this launch was launched in.
	 */
	private String fMode;

	/**
	 * Table of client defined attributes
	 */
	private HashMap<String, String> fAttributes;

	/**
	 * Flag indicating that change notification should
	 * be suppressed. <code>true</code> until this
	 * launch has been initialized.
	 */
	private boolean fSuppressChange = true;

	/**
	 * Constructs a launch with the specified attributes.
	 *
	 * @param launchConfiguration the configuration that was launched
	 * @param mode the mode of this launch - run or debug (constants
	 *  defined by <code>ILaunchManager</code>)
	 * @param locator the source locator to use for this debug session, or
	 * 	<code>null</code> if not supported
	 */
	public Launch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator) {
		fConfiguration = launchConfiguration;
		setSourceLocator(locator);
		fMode = mode;
		fSuppressChange = false;
		getLaunchManager().addLaunchListener(this);
		getLaunchManager().addLaunchConfigurationListener(this);
	}

	/**
	 * Registers debug event listener.
	 */
	private void addEventListener() {
		DebugPlugin.getDefault().addDebugEventListener(this);
	}

	/**
	 * Removes debug event listener.
	 */
	private void removeEventListener() {
		DebugPlugin.getDefault().removeDebugEventListener(this);
	}

	/**
	 * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
	 */
	@Override
	public boolean canTerminate() {
		 readLock.lock();
		try {
			for (IProcess process : getProcesses0()) {
				if (process.canTerminate()) {
					return true;
				}
			}
			for (IDebugTarget target : getDebugTargets0()) {
				if (target.canTerminate() || target.canDisconnect()) {
					return true;
				}
			}
		} finally {
			 readLock.unlock();
		}
		return false;
	}

	/**
	 * @see ILaunch#getChildren()
	 */
	@Override
	public Object[] getChildren() {
		readLock.lock();
		ArrayList<Object> children;
		try {
			children = new ArrayList<>(getDebugTargets0());
			children.addAll(getProcesses0());
		} finally {
			readLock.unlock();
		}
		return children.toArray();
	}

	/**
	 * @see ILaunch#getDebugTarget()
	 */
	@Override
	public IDebugTarget getDebugTarget() {
		readLock.lock();
		try {
			if (!getDebugTargets0().isEmpty()) {
				return getDebugTargets0().get(0);
			}
		} finally {
			readLock.unlock();
		}
		return null;
	}

	/**
	 * @see ILaunch#getProcesses()
	 */
	@Override
	public IProcess[] getProcesses() {
		readLock.lock();
		try {
			return getProcesses0().toArray(new IProcess[getProcesses0().size()]);
		} finally {
			readLock.unlock();
		}
	}

	/**
	 * Returns the processes associated with this
	 * launch, in its internal form - a list.
	 *
	 * @return list of processes
	 */
	protected List<IProcess> getProcesses0() {
		return fProcesses;
	}

	/**
	 * @see ILaunch#getSourceLocator()
	 */
	@Override
	public ISourceLocator getSourceLocator() {
		return fLocator;
	}

	/**
	 * @see ILaunch#setSourceLocator(ISourceLocator)
	 */
	@Override
	public void setSourceLocator(ISourceLocator sourceLocator) {
		fLocator = sourceLocator;
	}

	/**
	 * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
	 */
	@Override
	public boolean isTerminated() {
		readLock.lock();
		try {
			if (getProcesses0().isEmpty() && getDebugTargets0().isEmpty()) {
				return false;
			}
			for (IProcess process : getProcesses0()) {
				if (!process.isTerminated()) {
					return false;
				}
			}
			for (IDebugTarget target : getDebugTargets0()) {
				if (!(target.isTerminated() || target.isDisconnected())) {
					return false;
				}
			}
		} finally {
			readLock.unlock();
		}
		return true;
	}

	/**
	 * @see org.eclipse.debug.core.model.ITerminate#terminate()
	 */
	@Override
	public void terminate() throws DebugException {
		MultiStatus status=
			new MultiStatus(DebugPlugin.getUniqueIdentifier(), DebugException.REQUEST_FAILED, DebugCoreMessages.Launch_terminate_failed, null);
		//stop targets first to free up and sockets, etc held by the target
		// terminate or disconnect debug target if it is still alive
		IDebugTarget[] targets = getDebugTargets();
		for (int i = 0; i < targets.length; i++) {
			IDebugTarget target= targets[i];
			if (target != null) {
				if (target.canTerminate()) {
					try {
						target.terminate();
					} catch (DebugException e) {
						status.merge(e.getStatus());
					}
				} else {
					if (target.canDisconnect()) {
						try {
							target.disconnect();
						} catch (DebugException de) {
							status.merge(de.getStatus());
						}
					}
				}
			}
		}
		//second kill the underlying process
		// terminate the system processes
		IProcess[] processes = getProcesses();
		for (int i = 0; i < processes.length; i++) {
			IProcess process = processes[i];
			if (process.canTerminate()) {
				try {
					process.terminate();
				} catch (DebugException e) {
					status.merge(e.getStatus());
				}
			}
		}
		if (status.isOK()) {
			return;
		}
		IStatus[] children= status.getChildren();
		if (children.length == 1) {
			throw new DebugException(children[0]);
		}
		throw new DebugException(status);
	}

	/**
	 * @see ILaunch#getLaunchMode()
	 */
	@Override
	public String getLaunchMode() {
		return fMode;
	}

	/**
	 * @see ILaunch#getLaunchConfiguration()
	 */
	@Override
	public ILaunchConfiguration getLaunchConfiguration() {
		return fConfiguration;
	}

	/**
	 * @see ILaunch#setAttribute(String, String)
	 */
	@Override
	public void setAttribute(String key, String value) {
		if (fAttributes == null) {
			fAttributes = new HashMap<>(5);
		}
		fAttributes.put(key, value);
	}

	/**
	 * @see ILaunch#getAttribute(String)
	 */
	@Override
	public String getAttribute(String key) {
		if (fAttributes == null) {
			return null;
		}
		return fAttributes.get(key);
	}

	/**
	 * @see ILaunch#getDebugTargets()
	 */
	@Override
	public IDebugTarget[] getDebugTargets() {
		readLock.lock();
		try {
			return fTargets.toArray(new IDebugTarget[fTargets.size()]);
		} finally {
			readLock.unlock();
		}
	}

	/**
	 * Returns the debug targets associated with this
	 * launch, in its internal form - a list
	 *
	 * @return list of debug targets
	 */
	protected List<IDebugTarget> getDebugTargets0() {
		return fTargets;
	}

	/**
	 * @see ILaunch#addDebugTarget(IDebugTarget)
	 */
	@Override
	public void addDebugTarget(IDebugTarget target) {
		if (target != null) {
			writeLock.lock();
			boolean changed = false;
			try {
				if (!getDebugTargets0().contains(target)) {
					addEventListener();
					changed = getDebugTargets0().add(target);
				}
			} finally {
				writeLock.unlock();
				if (changed) {
					fireChanged();
				}
			}
		}
	}

	/**
	 * @see ILaunch#removeDebugTarget(IDebugTarget)
	 */
	@Override
	public void removeDebugTarget(IDebugTarget target) {
		if (target != null) {
			writeLock.lock();
			boolean changed = false;
			try {
				changed = getDebugTargets0().remove(target);
			} finally {
				writeLock.unlock();
				if (changed) {
					fireChanged();
				}
			}
		}
	}

	/**
	 * @see ILaunch#addProcess(IProcess)
	 */
	@Override
	public void addProcess(IProcess process) {
		if (process != null) {
			writeLock.lock();
			boolean changed = false;
			try {
				if (!getProcesses0().contains(process)) {
					addEventListener();
					changed = getProcesses0().add(process);
				}
			} finally {
				writeLock.unlock();
				if (changed) {
					fireChanged();
				}
			}
		}
	}

	/**
	 * @see ILaunch#removeProcess(IProcess)
	 */
	@Override
	public void removeProcess(IProcess process) {
		if (process != null) {
			writeLock.lock();
			boolean changed = false;
			try {
				changed = getProcesses0().remove(process);
			} finally {
				writeLock.unlock();
				if (changed) {
					fireChanged();
				}
			}
		}
	}

	/**
	 * Adds the given processes to this launch.
	 *
	 * @param processes processes to add
	 */
	protected void addProcesses(IProcess[] processes) {
		if (processes != null) {
			for (int i = 0; i < processes.length; i++) {
				addProcess(processes[i]);
				fireChanged();
			}
		}
	}

	/**
	 * Notifies listeners that this launch has changed.
	 * Has no effect of this launch has not yet been
	 * properly created/initialized.
	 */
	protected void fireChanged() {
		if (!fSuppressChange) {
			((LaunchManager)getLaunchManager()).fireUpdate(this, LaunchManager.CHANGED);
			((LaunchManager)getLaunchManager()).fireUpdate(new ILaunch[] {this}, LaunchManager.CHANGED);
		}
	}

	/**
	 * Notifies listeners that this launch has terminated.
	 * Has no effect of this launch has not yet been
	 * properly created/initialized.
	 */
	protected void fireTerminate() {
		if (!fSuppressChange) {
			((LaunchManager)getLaunchManager()).fireUpdate(this, LaunchManager.TERMINATE);
			((LaunchManager)getLaunchManager()).fireUpdate(new ILaunch[] {this}, LaunchManager.TERMINATE);
		}
		removeEventListener();
	}

	/**
	 * @see ILaunch#hasChildren()
	 */
	@Override
	public boolean hasChildren() {
		return getProcesses0().size() > 0 || (getDebugTargets0().size() > 0);
	}

	/**
     * Returns whether any processes or targets can be disconnected.
     * Ones that are already terminated or disconnected are ignored.
     *
	 * @see org.eclipse.debug.core.model.IDisconnect#canDisconnect()
	 */
	@Override
	public boolean canDisconnect() {
		readLock.lock();
		try {
			for (IProcess process : getProcesses0()) {
				if (process instanceof IDisconnect) {
					if (((IDisconnect) process).canDisconnect()) {
						return true;
					}
				}
			}
			for (IDebugTarget target : getDebugTargets0()) {
				if (target.canDisconnect()) {
					return true;
				}
			}
		} finally {
			readLock.unlock();
		}
        return false;
	}

	/**
	 * @see org.eclipse.debug.core.model.IDisconnect#disconnect()
	 */
	@Override
	public void disconnect() throws DebugException {
		readLock.lock();
		try {
			for (IProcess process : getProcesses0()) {
				if (process instanceof IDisconnect) {
					IDisconnect dis = (IDisconnect) process;
					if (dis.canDisconnect()) {
						dis.disconnect();
					}
				}
			}
			for (IDebugTarget target : getDebugTargets0()) {
				if (target.canDisconnect()) {
					target.disconnect();
				}
			}
		} finally {
			readLock.unlock();
		}
	}

	/**
     * Returns whether all of the contained targets and processes are
     * disconnected. Processes that don't support disconnecting are not
     * counted.
     *
	 * @see org.eclipse.debug.core.model.IDisconnect#isDisconnected()
	 */
	@Override
	public boolean isDisconnected() {
		readLock.lock();
		try {
			for (IProcess process : getProcesses0()) {
				if (process instanceof IDisconnect) {
					if (!((IDisconnect) process).isDisconnected()) {
						return false;
					}
				}
			}
			for (IDebugTarget target : getDebugTargets0()) {
				if (!target.isDisconnected()) {
					return false;
				}
			}
		} finally {
			readLock.unlock();
		}
        // only return true if there are processes or targets that are disconnected
        return hasChildren();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.ILaunchListener#launchRemoved(org.eclipse.debug.core.ILaunch)
	 */
	@Override
	public void launchRemoved(ILaunch launch) {
		if (this.equals(launch)) {
			removeEventListener();
			getLaunchManager().removeLaunchListener(this);
			getLaunchManager().removeLaunchConfigurationListener(this);
		}
	}

	/**
	 * Returns the launch manager.
	 *
	 * @return the launch manager.
	 */
	protected ILaunchManager getLaunchManager() {
		return DebugPlugin.getDefault().getLaunchManager();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.ILaunchListener#launchAdded(org.eclipse.debug.core.ILaunch)
	 */
	@Override
	public void launchAdded(ILaunch launch) {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.ILaunchListener#launchChanged(org.eclipse.debug.core.ILaunch)
	 */
	@Override
	public void launchChanged(ILaunch launch) {
	}

	/* (non-Javadoc)
	 *
	 * If the launch configuration this launch is associated with is
	 * moved, update the underlying handle to the new location.
	 *
	 * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationAdded(org.eclipse.debug.core.ILaunchConfiguration)
	 */
	@Override
	public void launchConfigurationAdded(ILaunchConfiguration configuration) {
		ILaunchConfiguration from = getLaunchManager().getMovedFrom(configuration);
		if (from != null && from.equals(getLaunchConfiguration())) {
			fConfiguration = configuration;
			fireChanged();
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationChanged(org.eclipse.debug.core.ILaunchConfiguration)
	 */
	@Override
	public void launchConfigurationChanged(ILaunchConfiguration configuration) {}

	/* (non-Javadoc)
	 *
	 * Update the launch configuration associated with this launch if the
	 * underlying configuration is deleted.
	 *
	 * @see org.eclipse.debug.core.ILaunchConfigurationListener#launchConfigurationRemoved(org.eclipse.debug.core.ILaunchConfiguration)
	 */
	@Override
	public void launchConfigurationRemoved(ILaunchConfiguration configuration) {
		if (configuration.equals(getLaunchConfiguration())) {
			if (getLaunchManager().getMovedTo(configuration) == null) {
				fConfiguration = null;
				fireChanged();
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.IDebugEventSetListener#handleDebugEvents(org.eclipse.debug.core.DebugEvent[])
	 */
	@Override
	public void handleDebugEvents(DebugEvent[] events) {
		for (int i = 0; i < events.length; i++) {
			DebugEvent event = events[i];
			if (event.getKind() == DebugEvent.TERMINATE) {
				Object object = event.getSource();
				ILaunch launch = null;
				if (object instanceof IProcess) {
					launch = ((IProcess)object).getLaunch();
				} else if (object instanceof IDebugTarget) {
					launch = ((IDebugTarget)object).getLaunch();
				}
				if (this.equals(launch)) {
					if (isTerminated()) {
						fireTerminate();
					}
				}
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.core.runtime.PlatformObject#getAdapter(java.lang.Class)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> adapter) {
		if (adapter.equals(ILaunch.class)) {
			return (T) this;
		}
		//CONTEXTLAUNCHING
		if(adapter.equals(ILaunchConfiguration.class)) {
			return (T) getLaunchConfiguration();
		}
		return super.getAdapter(adapter);
	}



}
