/*****************************************************************
 * Copyright (c) 2010, 2015 Texas Instruments 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:
 *     Patrick Chuong (Texas Instruments) - Pin and Clone Supports (331781)
 *     Patrick Chuong (Texas Instruments) - Add support for icon overlay in the debug view (Bug 334566)
 *****************************************************************/
package org.eclipse.cdt.dsf.gdb.internal.ui;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.RejectedExecutionException;
import java.util.concurrent.TimeUnit;

import org.eclipse.cdt.debug.ui.IPinProvider;
import org.eclipse.cdt.debug.ui.PinElementHandle;
import org.eclipse.cdt.dsf.concurrent.DataRequestMonitor;
import org.eclipse.cdt.dsf.concurrent.ImmediateInDsfExecutor;
import org.eclipse.cdt.dsf.concurrent.Query;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.datamodel.IDMEvent;
import org.eclipse.cdt.dsf.debug.service.IProcesses;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IProcessDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMContext;
import org.eclipse.cdt.dsf.debug.service.IProcesses.IThreadDMData;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IExitedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IResumedDMEvent;
import org.eclipse.cdt.dsf.debug.service.IRunControl.IStartedDMEvent;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlDMContext;
import org.eclipse.cdt.dsf.debug.service.command.ICommandControlService.ICommandControlShutdownDMEvent;
import org.eclipse.cdt.dsf.debug.ui.viewmodel.launch.StateChangedEvent;
import org.eclipse.cdt.dsf.mi.service.IMIContainerDMContext;
import org.eclipse.cdt.dsf.mi.service.IMIExecutionDMContext;
import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
import org.eclipse.cdt.dsf.service.DsfServicesTracker;
import org.eclipse.cdt.dsf.service.DsfSession;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.ui.IWorkbenchPart;

/**
 * GDB pin provider implementation.
 */
public class GdbPinProvider implements IPinProvider {
	private static class GdbPinElementColorDescriptor implements IPinElementColorDescriptor {
		int fColor = GREEN;

		GdbPinElementColorDescriptor(int color) {
			fColor = color;
		}

		@Override
		public int getOverlayColor() {
			return fColor;
		}

		@Override
		public ImageDescriptor getToolbarIconDescriptor() {
			return null;
		}
	}

	/**
	 * A set of pinned element handles and their callback.
	 */
	private static Map<IPinElementHandle, IPinModelListener> gsPinnedHandles = Collections
			.synchronizedMap(new HashMap<IPinElementHandle, IPinModelListener>());

	/**
	 * Dsf session.
	 */
	private final DsfSession fSession;

	/**
	 * Constructor.
	 *
	 * @param session
	 */
	public GdbPinProvider(DsfSession session) {
		fSession = session;

		session.getExecutor().execute(() -> fSession.addServiceEventListener(GdbPinProvider.this, null));
	}

	/**
	 * Dispose all resources.
	 */
	public void dispose() {
		try {
			fSession.getExecutor().execute(() -> fSession.removeServiceEventListener(GdbPinProvider.this));
		} catch (RejectedExecutionException e) {
			// Session already gone.
		}
	}

	/**
	 * Returns the pinned element handles.
	 *
	 * @return the element handles.
	 */
	public static Set<IPinElementHandle> getPinnedHandles() {
		return gsPinnedHandles.keySet();
	}

	private static IMIExecutionDMContext getExecutionDmc(IDMContext dmc) {
		return DMContexts.getAncestorOfType(dmc, IMIExecutionDMContext.class);
	}

	private static IProcessDMContext getProcessDmc(IDMContext dmc) {
		return DMContexts.getAncestorOfType(dmc, IProcessDMContext.class);
	}

	private IThreadDMData getData(final IThreadDMContext threadDmc) {
		if (threadDmc == null || !fSession.isActive())
			return null;

		IThreadDMData data = null;
		final DsfServicesTracker tracker = new DsfServicesTracker(GdbUIPlugin.getBundleContext(), fSession.getId());
		try {
			Query<IThreadDMData> query = new Query<>() {
				@Override
				protected void execute(final DataRequestMonitor<IThreadDMData> rm) {
					final IProcesses processes = tracker.getService(IProcesses.class);
					if (processes != null) {
						processes.getExecutionData(threadDmc, rm);
					} else {
						rm.setData(null);
						rm.done();
					}
				}
			};

			ImmediateInDsfExecutor immediateExecutor = new ImmediateInDsfExecutor(fSession.getExecutor());
			immediateExecutor.execute(query);
			data = query.get(2, TimeUnit.SECONDS); // timeout in 2 seconds, in case the call to execute got stuck
		} catch (Exception e) {
			GdbUIPlugin.log(e);
		} finally {
			if (tracker != null)
				tracker.dispose();
		}
		return data;
	}

	private String getLabel(IThreadDMData data) {
		String label = ""; //$NON-NLS-1$
		if (data != null) {
			String name = data.getName();
			String id = data.getId();
			if (name != null && !name.isEmpty())
				label = name;
			else if (id != null && !id.isEmpty())
				label = id;
		}
		return label;
	}

	private String getCombinedLabels(IThreadDMContext processDmc, IMIExecutionDMContext execDmc) {
		// get the process label
		IThreadDMData processData = getData(processDmc);
		String label = getLabel(processData);

		// get the execution (thread) context label
		if (execDmc != null) {
			String threadId = execDmc.getThreadId();
			label += !label.isEmpty() ? ": " : ""; //$NON-NLS-1$//$NON-NLS-2$
			label += "Thread [" + threadId + "]"; //$NON-NLS-1$//$NON-NLS-2$
		}
		return label;
	}

	@Override
	public boolean isPinnable(IWorkbenchPart part, Object debugContext) {
		if (debugContext instanceof IAdaptable) {
			return ((IAdaptable) debugContext).getAdapter(IDMContext.class) != null;
		}
		return false;
	}

	@Override
	public IPinElementHandle pin(IWorkbenchPart part, Object debugContext, IPinModelListener listener) {
		Object pinContext = debugContext;
		String label = ""; //$NON-NLS-1$
		String sessionId = ""; //$NON-NLS-1$

		IDMContext dmc = null;
		if (debugContext instanceof IAdaptable) {
			dmc = ((IAdaptable) debugContext).getAdapter(IDMContext.class);

			if (dmc != null) {
				sessionId = dmc.getSessionId() + "."; //$NON-NLS-1$
				IMIExecutionDMContext execDmc = getExecutionDmc(dmc);
				IProcessDMContext processDmc = getProcessDmc(dmc);

				label = getCombinedLabels(processDmc, execDmc);

				// set the pin context to a thread if it exist
				if (execDmc != null) {
					dmc = execDmc;
					pinContext = execDmc;

					// otherwise, set it to the DM context
				} else {
					pinContext = dmc;
				}
			}
		}

		IPinElementColorDescriptor colorDesc = new GdbPinElementColorDescriptor(
				GdbPinColorTracker.INSTANCE.addRef(sessionId + label));
		PinElementHandle handle = new PinElementHandle(pinContext, label, colorDesc);
		gsPinnedHandles.put(handle, listener);
		dispatchChangedEvent(dmc);

		return handle;
	}

	@Override
	public void unpin(IWorkbenchPart part, IPinElementHandle handle) {
		// remove the handle from the cache
		gsPinnedHandles.remove(handle);

		// dispatch the event to update the handle DM context
		Object debugContext = handle.getDebugContext();
		if (debugContext instanceof IAdaptable) {
			IDMContext dmc = ((IAdaptable) debugContext).getAdapter(IDMContext.class);
			GdbPinColorTracker.INSTANCE.removeRef(dmc.getSessionId() + "." + handle.getLabel()); //$NON-NLS-1$
			dispatchChangedEvent(dmc);

		}
	}

	@Override
	public boolean isPinnedTo(Object debugContext, IPinElementHandle handle) {
		Object handleDebugContext = handle.getDebugContext();

		if (debugContext instanceof IAdaptable && handleDebugContext instanceof IAdaptable) {
			IDMContext dmc = ((IAdaptable) debugContext).getAdapter(IDMContext.class);
			IDMContext hDmc = ((IAdaptable) handleDebugContext).getAdapter(IDMContext.class);

			if (dmc != null && hDmc != null) {
				if (dmc.getSessionId().equals(hDmc.getSessionId())) {
					IMIExecutionDMContext execDmc = getExecutionDmc(dmc);
					IProcessDMContext processDmc = getProcessDmc(dmc);

					String label = getCombinedLabels(processDmc, execDmc);
					return label.equals(handle.getLabel());
				}
			}
		}
		return false;
	}

	/**
	 * Dispatch the change event for the given DM context.
	 *
	 * @param dmc the DM context
	 */
	private void dispatchChangedEvent(IDMContext dmc) {
		if (dmc == null)
			return;

		try {
			DsfSession session = DsfSession.getSession(dmc.getSessionId());
			if (session != null && session.isActive())
				session.dispatchEvent(new StateChangedEvent(dmc), null);
		} catch (RejectedExecutionException e) {
			// Session already gone.
		}
	}

	/**
	 * Handle start event and re-attach the DM context to the pinned handles. The DM context
	 * is used for dispatching event to update the element label.
	 */
	@DsfServiceEventHandler
	public void handleEvent(final IStartedDMEvent event) {
		final IDMContext eventDmc = event.getDMContext();
		final IMIExecutionDMContext eventExecDmc = getExecutionDmc(eventDmc);
		final IProcessDMContext eventProcessDmc = getProcessDmc(eventDmc);

		if (eventProcessDmc != null) {
			for (final IPinElementHandle h : getPinnedHandles()) {
				new Job("Updating pin handler debug context") { //$NON-NLS-1$
					{
						setPriority(INTERACTIVE);
					}

					@Override
					protected IStatus run(IProgressMonitor monitor) {
						// only attach to the same pin handle if the session is not active
						PinElementHandle handle = ((PinElementHandle) h);
						Object handleDebugContext = handle.getDebugContext();
						if (handleDebugContext instanceof IAdaptable) {
							IDMContext handleDmc = ((IAdaptable) handleDebugContext).getAdapter(IDMContext.class);
							if (handleDmc != null) {
								DsfSession session = DsfSession.getSession(handleDmc.getSessionId());
								if (session == null || !session.isActive()) {
									String handleLabel = handle.getLabel();
									String label = getCombinedLabels(eventProcessDmc, eventExecDmc);

									if (label.equals(handleLabel)) {
										IDMContext newDmc = eventExecDmc != null ? eventExecDmc : eventDmc;
										handle.setDebugContext(newDmc);
										dispatchChangedEvent(newDmc);
									}
								}
							}
						}
						return Status.OK_STATUS;
					}
				}.schedule();
			}
		}
	}

	@DsfServiceEventHandler
	public void handleEvent(final ICommandControlShutdownDMEvent event) {
		handleInvalidModelContext(event);
	}

	@DsfServiceEventHandler
	public void handleEvent(final IExitedDMEvent event) {
		handleInvalidModelContext(event);
	}

	@DsfServiceEventHandler
	public void handleEvent(final IResumedDMEvent event) {
		handleInvalidModelContext(event);
	}

	private void handleInvalidModelContext(IDMEvent<?> event) {
		Set<Entry<IPinElementHandle, IPinModelListener>> entries = gsPinnedHandles.entrySet();
		for (final Entry<IPinElementHandle, IPinModelListener> e : entries) {
			final IPinModelListener listener = e.getValue();
			if (listener != null) {
				IPinElementHandle handle = e.getKey();

				Object handleObject = handle.getDebugContext();
				if (handleObject instanceof IDMContext) {
					IDMContext handleDmc = (IDMContext) handleObject;
					IDMContext eventDmc = event.getDMContext();

					// First check if we have a thread.  We must use IMIExecutionDMContext and not
					// IExecutionDMContext because IExecutionDMContext also represents a process
					IMIExecutionDMContext execEventDmc = DMContexts.getAncestorOfType(eventDmc,
							IMIExecutionDMContext.class);
					IMIExecutionDMContext execHandleDmc = DMContexts.getAncestorOfType(handleDmc,
							IMIExecutionDMContext.class);

					// Make sure both dmcs are not null to know if we should compare thread dmcs or container dmcs
					if (execEventDmc != null && execHandleDmc != null) {
						// It is a thread event, but is it the same as the pin handle?
						if (execEventDmc.equals(execHandleDmc)) {
							fireModleChangeEvent(listener, null);
						}
						continue;
					}

					// If we weren't dealing with a thread for either the event or the handle,
					// let's check for IMIContainerDMContext
					IMIContainerDMContext procEventDmc = DMContexts.getAncestorOfType(eventDmc,
							IMIContainerDMContext.class);
					IMIContainerDMContext procHandleDmc = DMContexts.getAncestorOfType(handleDmc,
							IMIContainerDMContext.class);
					if (procEventDmc != null && procHandleDmc != null) {
						if (procEventDmc.equals(procHandleDmc)) {
							fireModleChangeEvent(listener, null);
						}
						continue;
					}

					// If we got a shutdown event
					if (eventDmc instanceof ICommandControlDMContext) {
						fireModleChangeEvent(listener, null);
						continue;
					}
				}
			}
		}
	}

	private void fireModleChangeEvent(final IPinModelListener listener, final ISelection selection) {
		new Job("Model Changed") { //$NON-NLS-1$
			{
				setSystem(true);
			}

			@Override
			protected IStatus run(IProgressMonitor arg0) {
				listener.modelChanged(selection);
				return Status.OK_STATUS;
			}
		}.schedule();
	}
}
