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

		// 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) {
				listener.eventSetComplete(event, fTarget, !resume, eventSet);
			}
		}

		// fire queued DEBUG events
		fireEvents(eventSet);

		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);
			}
		}
	}

}
