/*******************************************************************************
 * 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();
			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);
			}
		}
	}

}
