/*******************************************************************************
 * Copyright (c) 2000, 2015 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.jdt.internal.debug.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
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.Job;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.jdt.debug.core.IJavaLineBreakpoint;
import org.eclipse.jdt.internal.debug.core.model.JDIDebugTarget;

import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.VirtualMachine;
import com.sun.jdi.event.Event;
import com.sun.jdi.event.EventIterator;
import com.sun.jdi.event.EventQueue;
import com.sun.jdi.event.EventSet;
import com.sun.jdi.event.ThreadDeathEvent;
import com.sun.jdi.event.VMDeathEvent;
import com.sun.jdi.event.VMDisconnectEvent;
import com.sun.jdi.event.VMStartEvent;
import com.sun.jdi.request.EventRequest;

/**
 * Dispatches events generated by an underlying VM. There is one event
 * dispatcher per JDI debug target.
 * <p>
 * Event listeners register with a debug target to handle specific event
 * requests. A debug target forwards event listeners and requests to its event
 * dispatcher. As events are received from the underlying VM, those listeners
 * that registered to handle the specific events are notified.
 * </p>
 * <p>
 * Events are processed in event sets. It is possible that one event can trigger
 * more than one event request to be processed. In such cases all event requests
 * triggered by that one event are processed, and each event listener votes on
 * whether the thread in which the event occurred should be resumed. A thread is
 * only resumed in if all event handlers agree that the thread should be
 * resumed.
 * </p>
 */

public class EventDispatcher implements Runnable {
	/**
	 * The debug target this event dispatcher belongs to.
	 */
	private JDIDebugTarget fTarget;
	/**
	 * Whether this dispatcher is shutdown.
	 */
	private volatile boolean fShutdown;
	/**
	 * Table of event listeners. Table is a mapping of <code>EventRequest</code>
	 * to <code>IJDIEventListener</code>.
	 */
	private HashMap<EventRequest, IJDIEventListener> fEventHandlers;

	/**
	 * Queue of debug model events to fire, created when processing events on
	 * the target VM. Keyed by event sets, processed independently.
	 */
	private Map<EventSet, List<DebugEvent>> fSetToQueue = new HashMap<>();

	/**
	 * Constructs a new event dispatcher listening for events originating from
	 * the specified debug target's underlying VM.
	 *
	 * @param target
	 *            the target this event dispatcher belongs to
	 */
	public EventDispatcher(JDIDebugTarget target) {
		fEventHandlers = new HashMap<>(10);
		fTarget = target;
		fShutdown = false;
	}

	/**
	 * Dispatch the given event set.
	 *
	 * @param eventSet
	 *            events to dispatch
	 */
	private void dispatch(EventSet eventSet) {
		if (isShutdown()) {
			return;
		}
		if (JDIDebugOptions.DEBUG_JDI_EVENTS) {
			EventIterator eventIter = eventSet.eventIterator();
			StringBuilder buf = new StringBuilder("JDI Event Set: {\n"); //$NON-NLS-1$
			while (eventIter.hasNext()) {
				buf.append(eventIter.next());
				if (eventIter.hasNext()) {
					buf.append(", "); //$NON-NLS-1$
				}
			}
			buf.append("}\n"); //$NON-NLS-1$
			JDIDebugOptions.trace(buf.toString());
		}
		EventIterator iter = eventSet.eventIterator();
		IJDIEventListener[] listeners = new IJDIEventListener[eventSet.size()];
		boolean vote = false;
		boolean resume = true;
		int index = -1;
		List<Event> deferredEvents = null;
		while (iter.hasNext()) {
			index++;
			if (isShutdown()) {
				return;
			}
			Event event = iter.nextEvent();
			if (event == null) {
				continue;
			}
			// Dispatch events to registered listeners, if any
			IJDIEventListener listener = fEventHandlers.get(event.request());
			listeners[index] = listener;
			if (listener != null) {
				if (listener instanceof IJavaLineBreakpoint) {
					// Event dispatch to conditional breakpoints is deferred
					// until after
					// other listeners vote.
					try {
						if (((IJavaLineBreakpoint) listener).isConditionEnabled()) {
							if (deferredEvents == null) {
								deferredEvents = new ArrayList<>(5);
							}
							deferredEvents.add(event);
							continue;
						}
					} catch (CoreException exception) {
						JDIDebugPlugin.log(exception);
					}
				}
				vote = true;
				resume = listener.handleEvent(event, fTarget, !resume, eventSet) && resume;
				continue;
			}

			// Dispatch VM start/end events
			if (event instanceof VMDeathEvent) {
				fTarget.handleVMDeath((VMDeathEvent) event);
				shutdown(); // stop listening for events
			} else if (event instanceof VMDisconnectEvent) {
				fTarget.handleVMDisconnect((VMDisconnectEvent) event);
				shutdown(); // stop listening for events
			} else if (event instanceof VMStartEvent) {
				fTarget.handleVMStart((VMStartEvent) event);
			} else {
				// not handled
			}
		}

		// process deferred conditional breakpoint events
		if (deferredEvents != null) {
			Iterator<Event> deferredIter = deferredEvents.iterator();
			while (deferredIter.hasNext()) {
				if (isShutdown()) {
					return;
				}
				Event event = deferredIter.next();
				if (event == null) {
					continue;
				}
				// Dispatch events to registered listeners, if any
				IJDIEventListener listener = fEventHandlers
						.get(event.request());
				if (listener != null) {
					vote = true;
					resume = listener.handleEvent(event, fTarget, !resume, eventSet) && resume;
					continue;
				}
			}
		}

		List<Runnable> threadDeathRunnables = new ArrayList<>();

		// notify handlers of the end result
		index = -1;
		iter = eventSet.eventIterator();
		while (iter.hasNext()) {
			index++;
			Event event = iter.nextEvent();
			// notify registered listener, if any
			IJDIEventListener listener = listeners[index];
			if (listener != null) {
				if (event instanceof ThreadDeathEvent) {
					final boolean res = resume;
					threadDeathRunnables.add(() -> listener.eventSetComplete(event, fTarget, !res, eventSet));
				} else {
					listener.eventSetComplete(event, fTarget, !resume, eventSet);
				}
			}
		}

		// fire queued DEBUG events
		fireEvents(eventSet);

		// Queue runnables which will remove terminated threads once other queued events are proceeded
		threadDeathRunnables.forEach(runnable -> DebugPlugin.getDefault().asyncExec(runnable));

		if (vote && resume) {
			try {
				eventSet.resume();
			} catch (VMDisconnectedException e) {
			} catch (RuntimeException e) {
				try {
					fTarget.targetRequestFailed(
							JDIDebugMessages.EventDispatcher_0, e);
				} catch (DebugException de) {
					JDIDebugPlugin.log(de);
				}
			}
		}
	}

	private boolean requiresExpressionEvaluation(EventSet eventSet) {
		EventIterator iter = eventSet.eventIterator();
		while (iter.hasNext()) {
			Event event = iter.nextEvent();
			if (event == null) {
				continue;
			}
			IJDIEventListener listener = fEventHandlers.get(event.request());
			if (listener instanceof IJavaLineBreakpoint) {
				try {
					if (((IJavaLineBreakpoint) listener).isConditionEnabled()) {
						return true;
					}
				}
				catch (CoreException e) {
					return true; // assume the worst
				}
			}
		}
		return false;
	}

	/** @noreference public for test purposes */
	public abstract class AbstractDispatchJob extends Job {
		protected AbstractDispatchJob(String name) {
			super(name);
		}

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

		@Override
		public String toString() {
			try {
				return super.toString() + " for [" + fTarget.getName() + "]"; //$NON-NLS-1$ //$NON-NLS-2$
			}
			catch (DebugException e) {
				return super.toString();
			}
		}
	}

	/**
	 * Continuously reads events that are coming from the event queue, until
	 * this event dispatcher is shutdown. A debug target starts a thread on this
	 * method on startup.
	 *
	 * @see #shutdown()
	 */
	@Override
	public void run() {
		VirtualMachine vm = fTarget.getVM();
		if (vm != null) {
			EventQueue q = vm.eventQueue();
			while (!isShutdown()) {
				try {
					EventSet eventSet;
					try {
						// Get the next event set.
						eventSet = q.remove(1000);
					} catch (VMDisconnectedException e) {
						break;
					}

					if (eventSet != null) {
						if (!requiresExpressionEvaluation(eventSet)) {
							dispatch(eventSet);
						} else {
							// 269231 always evaluate expressions in a separate job to avoid deadlocks
							Job job = new AbstractDispatchJob("JDI Expression Evaluation Event Dispatch") { //$NON-NLS-1$
								@Override
								protected IStatus run(IProgressMonitor monitor) {
									dispatch(eventSet);
									return Status.OK_STATUS;
								}
							};
							job.setSystem(true);
							job.schedule();
						}
					}
				} catch (InterruptedException e) {
					break;
				}
			}
		}
	}

	/**
	 * Shutdown this event dispatcher - i.e. causes this event dispatcher to
	 * stop reading and dispatching events from the event queue. The thread
	 * associated with this runnable will exit.
	 */
	public void shutdown() {
		fShutdown = true;
		Job.getJobManager().cancel(this);
	}

	/**
	 * Returns whether this event dispatcher has been shutdown.
	 *
	 * @return whether this event dispatcher has been shutdown
	 */
	private boolean isShutdown() {
		return fShutdown;
	}

	/**
	 * Registers the given listener for with the given event request. When an
	 * event is received from the underlying VM, that is associated with the
	 * given event request, the listener will be notified.
	 *
	 * @param listener
	 *            the listener to register
	 * @param request
	 *            the event request associated with events the listener is
	 *            interested in
	 */
	public void addJDIEventListener(IJDIEventListener listener,
			EventRequest request) {
		fEventHandlers.put(request, listener);
	}

	/**
	 * De-registers the given listener and event request. The listener will no
	 * longer be notified of events associated with the request. Listeners are
	 * responsible for deleting the associated event request if required.
	 *
	 * @param listener
	 *            the listener to de-register
	 * @param request
	 *            the event request to de-register
	 */
	public void removeJDIEventListener(IJDIEventListener listener, EventRequest request) {
		fEventHandlers.remove(request);
	}

	/**
	 * Adds the given event to the queue of debug events to fire when done
	 * dispatching events from the given event set.
	 *
	 * @param event
	 *            the event to queue
	 * @param set
	 *            event set the event is associated with
	 */
	public void queue(DebugEvent event, EventSet set) {
		synchronized (fSetToQueue) {
			List<DebugEvent> list = fSetToQueue.get(set);
			if (list == null) {
				list = new ArrayList<>(5);
				fSetToQueue.put(set, list);
			}
			list.add(event);
		}
	}

	/**
	 * Fires debug events in the event queue associated with the given event
	 * set, and clears the queue.
	 * @param set the set to fire events for
	 */
	private void fireEvents(EventSet set) {
		DebugPlugin plugin = DebugPlugin.getDefault();
		if (plugin != null) { // check that not in the process of shutting down
			List<DebugEvent> list = null;
			synchronized (fSetToQueue) {
				list = fSetToQueue.remove(set);
			}
			if (list != null) {
				DebugEvent[] events = list.toArray(new DebugEvent[list.size()]);
				plugin.fireDebugEventSet(events);
			}
		}
	}

}
