/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * 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();
			StringBuffer buf = new StringBuffer("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);
			}
		}
	}

}
