/*******************************************************************************
 * Copyright (c) 2000, 2019 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
 *******************************************************************************/
package org.eclipse.debug.internal.ui.views.console;


import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchListener;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.internal.ui.DebugUIPlugin;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.console.ConsoleColorProvider;
import org.eclipse.debug.ui.console.IConsoleColorProvider;
import org.eclipse.debug.ui.console.IConsoleLineTracker;
import org.eclipse.jface.text.IDocument;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.IConsoleManager;

import com.ibm.icu.text.MessageFormat;

/**
 * Creates documents for processes as they are registered with a launch.
 * The singleton manager is accessible from the debug UI plugin.
 */
public class ProcessConsoleManager implements ILaunchListener {

	/**
	 * Creates console for given process
	 */
	private final class ConsoleCreation extends Job {
		private final ILaunch launch;
		private final IProcess process;

		ConsoleCreation(ILaunch launch, IProcess process) {
			super("Creating console for " + process.getLabel()); //$NON-NLS-1$
			this.launch = launch;
			this.process = process;
			setSystem(true);
			setUser(false);
		}

		@Override
		protected IStatus run(IProgressMonitor monitor) {
			if (monitor.isCanceled() || getConsoleDocument(process) != null) {
				return Status.CANCEL_STATUS;
			}
			IConsoleColorProvider colorProvider = getColorProvider(process.getAttribute(IProcess.ATTR_PROCESS_TYPE));
			String encoding = launch.getAttribute(DebugPlugin.ATTR_CONSOLE_ENCODING);
			ProcessConsole pc = new ProcessConsole(process, colorProvider, encoding);
			pc.setAttribute(IDebugUIConstants.ATTR_CONSOLE_PROCESS, process);

			// add new console to console manager.
			ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { pc });

			// If a launch is removed the associated console is removed too. It can happen
			// that the launch is removed even before the console could be created.
			// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=546710#c13
			ILaunchManager launchManager = DebugPlugin.getDefault().getLaunchManager();
			if (!launchManager.isRegistered(launch)) {
				removeLaunch(launch);
			}
			return Status.OK_STATUS;
		}

		@Override
		public boolean belongsTo(Object family) {
			return process == family || ProcessConsoleManager.class == family;
		}

		@Override
		public boolean shouldSchedule() {
			Job[] jobs = Job.getJobManager().find(process);
			for (Job job : jobs) {
				if (job instanceof ConsoleCreation) {
					return false;
				}
			}
			return true;
		}
	}

	/**
	 * Console document content provider extensions, keyed by extension id
	 */
	private Map<String, IConfigurationElement> fColorProviders;

	/**
	 * The default color provider. Used if no color provider is contributed
	 * for the given process type.
	 */
	private IConsoleColorProvider fDefaultColorProvider;

	/**
	 * Console line trackers; keyed by process type to list of trackers (1:N)
	 */
	private Map<String, List<IConfigurationElement>> fLineTrackers;

	/**
	 * Map of processes for a launch to compute removed processes
	 */
	private Map<ILaunch, IProcess[]> fProcesses;

	/**
	 * Lock for fLineTrackers
	 */
	private Object fLineTrackersLock = new Object();
	/**
	 * @see ILaunchListener#launchRemoved(ILaunch)
	 */
	@Override
	public void launchRemoved(ILaunch launch) {
		removeLaunch(launch);
	}

	protected void removeLaunch(ILaunch launch) {
		for (IProcess process : launch.getProcesses()) {
			removeProcess(process);
		}
		if (fProcesses != null) {
			fProcesses.remove(launch);
		}
	}

	/**
	 * Removes the console and document associated with the given process.
	 *
	 * @param iProcess process to clean up
	 */
	private void removeProcess(IProcess iProcess) {
		IConsole console = getConsole(iProcess);

		if (console != null) {
			IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
			manager.removeConsoles(new IConsole[]{console});
		}
	}

	/**
	 * Returns the console for the given process, or <code>null</code> if none.
	 *
	 * @param process
	 * @return the console for the given process, or <code>null</code> if none
	 */
	public IConsole getConsole(IProcess process) {
		IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
		for (IConsole console : manager.getConsoles()) {
			if (console instanceof ProcessConsole) {
				ProcessConsole pc = (ProcessConsole)console;
				if (pc.getProcess().equals(process)) {
					return pc;
				}
			}
		}
		return null;
	}

	/**
	 * @see ILaunchListener#launchAdded(ILaunch)
	 */
	@Override
	public void launchAdded(ILaunch launch) {
		launchChanged(launch);
	}

	/**
	 * @see ILaunchListener#launchChanged(ILaunch)
	 */
	@Override
	public void launchChanged(final ILaunch launch) {
		IProcess[] processes= launch.getProcesses();
		for (IProcess process : processes) {
			if (process.getStreamsProxy() == null) {
				continue;
			}
			if (getConsoleDocument(process) == null) {
				// create a new console in a separated thread, see bug 355011.
				Job job = new ConsoleCreation(launch, process);
				job.schedule();
			}
		}
		List<IProcess> removed = getRemovedProcesses(launch);
		if (removed != null) {
			for (IProcess p : removed) {
				removeProcess(p);
			}
		}
	}

	/**
	 * Returns the document for the process, or <code>null</code>
	 * if none.
	 */
	public IDocument getConsoleDocument(IProcess process) {
		ProcessConsole console = (ProcessConsole) getConsole(process);
		return (console != null ? console.getDocument() : null);
	}

	/**
	 * Called by the debug ui plug-in on startup.
	 * The console document manager starts listening for
	 * launches to be registered and initializes if any launches
	 * already exist.
	 */
	public void startup() {
		ILaunchManager launchManager= DebugPlugin.getDefault().getLaunchManager();
		launchManager.addLaunchListener(this);

		//set up the docs for launches already registered
		for (ILaunch launch : launchManager.getLaunches()) {
			launchAdded(launch);
		}
	}

	/**
	 * Called by the debug ui plug-in on shutdown.
	 * The console document manager de-registers as a
	 * launch listener and kills all existing console documents.
	 */
	public void shutdown() {
		Job.getJobManager().cancel(ProcessConsoleManager.class);
		ILaunchManager launchManager= DebugPlugin.getDefault().getLaunchManager();
		for (ILaunch launch : launchManager.getLaunches()) {
			removeLaunch(launch);
		}
		launchManager.removeLaunchListener(this);
		if (fProcesses != null) {
			fProcesses.clear();
		}
	}

	/**
	 * Returns a new console document color provider extension for the given
	 * process type, or <code>null</code> if none.
	 *
	 * @param type corresponds to <code>IProcess.ATTR_PROCESS_TYPE</code>
	 * @return IConsoleColorProvider
	 */
	public IConsoleColorProvider getColorProvider(String type) {
		if (fColorProviders == null) {
			fColorProviders = new HashMap<>();
			IExtensionPoint extensionPoint= Platform.getExtensionRegistry().getExtensionPoint(DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.EXTENSION_POINT_CONSOLE_COLOR_PROVIDERS);
			for (IConfigurationElement extension : extensionPoint.getConfigurationElements()) {
				fColorProviders.put(extension.getAttribute("processType"), extension); //$NON-NLS-1$
			}
		}
		IConfigurationElement extension = fColorProviders.get(type);
		if (extension != null) {
			try {
				Object colorProvider = extension.createExecutableExtension("class"); //$NON-NLS-1$
				if (colorProvider instanceof IConsoleColorProvider) {
					return (IConsoleColorProvider)colorProvider;
				}
				DebugUIPlugin.logErrorMessage(MessageFormat.format(
						"Extension {0} must specify an instanceof IConsoleColorProvider for class attribute.", //$NON-NLS-1$
						new Object[] { extension.getDeclaringExtension().getUniqueIdentifier() }));
			} catch (CoreException e) {
				DebugUIPlugin.log(e);
			}
		}
		//no color provider found of specified type, return default color provider.
		if (fDefaultColorProvider == null) {
			fDefaultColorProvider = new ConsoleColorProvider();
		}
		return fDefaultColorProvider;
	}

	/**
	 * Returns the Line Trackers for a given process type.
	 * @param process The process for which line trackers are required.
	 * @return An array of line trackers which match the given process type.
	 */
	public IConsoleLineTracker[] getLineTrackers(IProcess process) {
		String type = process.getAttribute(IProcess.ATTR_PROCESS_TYPE);

		if (fLineTrackers == null) {
			synchronized (fLineTrackersLock) { // can't use fLineTrackers as lock as it is null here
				fLineTrackers = new HashMap<>();
				IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(DebugUIPlugin.getUniqueIdentifier(), IDebugUIConstants.EXTENSION_POINT_CONSOLE_LINE_TRACKERS);
				for (IConfigurationElement extension : extensionPoint.getConfigurationElements()) {
					String processType = extension.getAttribute("processType"); //$NON-NLS-1$
					List<IConfigurationElement> list = fLineTrackers.get(processType);
					if (list == null) {
						list = new ArrayList<>();
						fLineTrackers.put(processType, list);
					}
					list.add(extension);
				}
			}
		}

		ArrayList<IConsoleLineTracker> trackers = new ArrayList<>();
		if (type != null) {
			List<IConfigurationElement> lineTrackerExtensions;
			synchronized (fLineTrackers) {// need to synchronize as the update to list might be still happening
				lineTrackerExtensions = fLineTrackers.get(type);
			}
			if(lineTrackerExtensions != null) {
				for (IConfigurationElement element : lineTrackerExtensions) {
					try {
						trackers.add((IConsoleLineTracker) element.createExecutableExtension("class")); //$NON-NLS-1$
					} catch (CoreException e) {
						DebugUIPlugin.log(e);
					}
				}
			}
		}
		return trackers.toArray(new IConsoleLineTracker[0]);
	}

	/**
	 * Returns the processes that have been removed from the given
	 * launch, or <code>null</code> if none.
	 *
	 * @param launch launch that has changed
	 * @return removed processes or <code>null</code>
	 */
	private List<IProcess> getRemovedProcesses(ILaunch launch) {
		List<IProcess> removed = null;
		if (fProcesses == null) {
			fProcesses = new HashMap<>();
		}
		IProcess[] old = fProcesses.get(launch);
		IProcess[] curr = launch.getProcesses();
		if (old != null) {
			for (IProcess process : old) {
				if (!contains(curr, process)) {
					if (removed == null) {
						removed = new ArrayList<>();
					}
					removed.add(process);
				}
			}
		}
		// update cache with current processes
		fProcesses.put(launch, curr);
		return removed;
	}

	/**
	 * Returns whether the given object is contained in the list.
	 *
	 * @param list list to search
	 * @param object object to search for
	 * @return whether the given object is contained in the list
	 */
	private boolean contains(Object[] list, Object object) {
		for (Object object2 : list) {
			if (object2.equals(object)) {
				return true;
			}
		}
		return false;
	}
}
