/*******************************************************************************
 * Copyright (c) 2010 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.wst.jsdt.debug.internal.crossfire.event;

import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.wst.jsdt.debug.core.jsdi.ThreadReference;
import org.eclipse.wst.jsdt.debug.core.jsdi.event.EventQueue;
import org.eclipse.wst.jsdt.debug.core.jsdi.event.EventSet;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.EventRequestManager;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.ResumeRequest;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.ScriptLoadRequest;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.SuspendRequest;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.ThreadEnterRequest;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.ThreadExitRequest;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.VMDeathRequest;
import org.eclipse.wst.jsdt.debug.internal.crossfire.CrossFirePlugin;
import org.eclipse.wst.jsdt.debug.internal.crossfire.Tracing;
import org.eclipse.wst.jsdt.debug.internal.crossfire.jsdi.CFLocation;
import org.eclipse.wst.jsdt.debug.internal.crossfire.jsdi.CFMirror;
import org.eclipse.wst.jsdt.debug.internal.crossfire.jsdi.CFScriptReference;
import org.eclipse.wst.jsdt.debug.internal.crossfire.jsdi.CFThreadReference;
import org.eclipse.wst.jsdt.debug.internal.crossfire.jsdi.CFVirtualMachine;
import org.eclipse.wst.jsdt.debug.internal.crossfire.transport.Attributes;
import org.eclipse.wst.jsdt.debug.internal.crossfire.transport.CFEventPacket;
import org.eclipse.wst.jsdt.debug.internal.crossfire.transport.JSON;
import org.eclipse.wst.jsdt.debug.transport.exception.DisconnectedException;
import org.eclipse.wst.jsdt.debug.transport.exception.TimeoutException;

/**
 * Default {@link EventQueue} for Crossfire
 * 
 * @since 1.0
 */
public class CFEventQueue extends CFMirror implements EventQueue {

	private static boolean TRACE = false;
	
	private EventRequestManager eventmgr = null;
	private boolean disposed = false;
	
	/**
	 * Constructor
	 * 
	 * @param vm
	 * @param manager
	 */
	public CFEventQueue(CFVirtualMachine vm, EventRequestManager manager) {
		super(vm);
		this.eventmgr = manager;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.event.EventQueue#remove()
	 */
	public EventSet remove() {
		return remove(-1);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.event.EventQueue#remove(int)
	 */
	public EventSet remove(int timeout) {
		try {
			while(true && !disposed) {
				CFEventPacket event = crossfire().receiveEvent(timeout);
				String name = event.getEvent();
				CFEventSet set = new CFEventSet(crossfire());
				if(CFEventPacket.CLOSED.equals(name)) {
					List deaths = eventmgr.vmDeathRequests();
					for (Iterator iter = deaths.iterator(); iter.hasNext();) {
						VMDeathRequest request = (VMDeathRequest) iter.next();
						set.add(new CFVMDeathEvent(crossfire(), request));
					}
					if(TRACE) {
						Tracing.writeString("QUEUE [event - "+CFEventPacket.CLOSED+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
				}
				else if(CFEventPacket.ON_BREAK.equals(name)) {
					if(TRACE) {
						Tracing.writeString("QUEUE [event - "+CFEventPacket.ON_BREAK+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
					String threadid = event.getContextId();
					if(threadid != null) {
						CFThreadReference thread = crossfire().findThread(threadid);
						set.setThread(thread);
						if(thread != null && !thread.isSuspended()) {
							List suspends = eventmgr.suspendRequests();
							for (Iterator iter = suspends.iterator(); iter.hasNext();) {
								SuspendRequest request = (SuspendRequest) iter.next();
								String url = (String) event.getBody().get(Attributes.URL);
								Number line = (Number) event.getBody().get(Attributes.LINE);
								CFScriptReference script = crossfire().findScript(url);
								if(script != null) {
									CFLocation loc = new CFLocation(crossfire(), script, null, line.intValue());
									set.add(new CFSuspendEvent(crossfire(), request, thread, loc));
								}
							}
							thread.markSuspended(true);
						}
						else {
							return null;
						}
					}
					else {
						return null;
					}
				}
				else if(CFEventPacket.ON_RESUME.equals(name)) {
					if(TRACE) {
						Tracing.writeString("QUEUE [event - "+CFEventPacket.ON_RESUME+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
					String threadid = event.getContextId();
					if(threadid != null) {
						CFThreadReference thread = crossfire().findThread(threadid);
						if(thread != null) {
							set.setThread(thread);
							List resumes = eventmgr.resumeRequests();
							for (Iterator iter = resumes.iterator(); iter.hasNext();) {
								ResumeRequest request = (ResumeRequest) iter.next();
								if(request.thread().equals(thread)) {
									CFLocation loc = new CFLocation(crossfire(), null, null, 0);
									set.add(new CFResumeEvent(crossfire(), request, thread, loc));
								}
							}
						}
						else {
							return null;
						}
					}
					else {
						return null;
					}
				}
				else if(CFEventPacket.ON_SCRIPT.equals(name)) {
					ThreadReference thread = crossfire().findThread(event.getContextId());
					if(thread != null) {
						set.setThread(thread);
						Map json = (Map) event.getBody().get(Attributes.SCRIPT);
						if(json != null) {
							CFScriptReference script = crossfire().addScript(event.getContextId(), json);
							List scripts = eventmgr.scriptLoadRequests();
							for (Iterator iter = scripts.iterator(); iter.hasNext();) {
								ScriptLoadRequest request = (ScriptLoadRequest) iter.next();
								set.add(new CFScriptLoadEvent(crossfire(), request, thread, script));
							}
						}
						else {
							return null;
						}
					}
					else {
						return null;
					}
					if(TRACE) {
						Tracing.writeString("QUEUE [event - "+CFEventPacket.ON_SCRIPT+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
				}
				else if(CFEventPacket.ON_CONTEXT_CREATED.equals(name)) {
					handleContext(set, event, false);
					if(TRACE) {
						Tracing.writeString("QUEUE [event - "+CFEventPacket.ON_CONTEXT_CREATED+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
				}
				else if(CFEventPacket.ON_CONTEXT_CHANGED.equals(name)) {
					handleContext(set, event, true);
					if(TRACE) {
						Tracing.writeString("QUEUE [event - "+CFEventPacket.ON_CONTEXT_CHANGED+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
				}
				else if(CFEventPacket.ON_CONTEXT_LOADED.equals(name)) {
					handleContext(set, event, true);
					if(TRACE) {
						Tracing.writeString("QUEUE [event - "+CFEventPacket.ON_CONTEXT_LOADED+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
				}
				else if(CFEventPacket.ON_CONTEXT_DESTROYED.equals(name)) {
					ThreadReference thread = crossfire().findThread(event.getContextId());
					crossfire().removeThread(event.getContextId());
					crossfire().removeScriptsForContext(event.getContextId());
					if(thread != null) {
						List threads = eventmgr.threadExitRequests();
						for (Iterator iter = threads.iterator(); iter.hasNext();) {
							ThreadExitRequest request = (ThreadExitRequest) iter.next();
							set.add(new CFThreadExitEvent(crossfire(), request, thread));
						}
					}
					else {
						return null;
					}
					if(TRACE) {
						Tracing.writeString("QUEUE [event - "+CFEventPacket.ON_CONTEXT_DESTROYED+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
				}
				else if(CFEventPacket.ON_CONSOLE_DEBUG.equals(name)) {
					List info = (List) event.getBody().get(Attributes.DATA);
					if(info != null) {
						log(IStatus.INFO, info);
					}
					if(TRACE) {
						Tracing.writeString("QUEUE [event - "+CFEventPacket.ON_CONSOLE_DEBUG+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
					return null;
				}
				else if(CFEventPacket.ON_CONSOLE_ERROR.equals(name)) {
					List info = (List) event.getBody().get(Attributes.VALUE);
					if(info != null) {
						log(IStatus.ERROR, info);
					}
					if(TRACE) {
						Tracing.writeString("QUEUE [event - "+CFEventPacket.ON_CONSOLE_ERROR+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
					return null;
				}
				else if(CFEventPacket.ON_CONSOLE_INFO.equals(name)) {
					List info = (List) event.getBody().get(Attributes.DATA);
					if(info != null) {
						log(IStatus.INFO, info);
					}
					if(TRACE) {
						Tracing.writeString("QUEUE [event - "+CFEventPacket.ON_CONSOLE_INFO+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
					return null;
				}
				else if(CFEventPacket.ON_CONSOLE_LOG.equals(name)) {
					List info = (List) event.getBody().get(Attributes.DATA);
					if(info != null) {
						log(IStatus.INFO, info);
					}
					if(TRACE) {
						Tracing.writeString("QUEUE [event - "+CFEventPacket.ON_CONSOLE_LOG+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
					return null;
				}
				else if(CFEventPacket.ON_CONSOLE_WARN.equals(name)) {
					List info = (List) event.getBody().get(Attributes.DATA);
					if(info != null) {
						log(IStatus.WARNING, info);
					}
					if(TRACE) {
						Tracing.writeString("QUEUE [event - "+CFEventPacket.ON_CONSOLE_WARN+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
					return null;
				}
				else if(CFEventPacket.ON_INSPECT_NODE.equals(name)) {
					if(TRACE) {
						Tracing.writeString("QUEUE [event - "+CFEventPacket.ON_INSPECT_NODE+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
					return null;
				}
				else if(CFEventPacket.ON_TOGGLE_BREAKPOINT.equals(name)) {
					/*Map body = event.getBody();
					String url = (String) body.get(Attributes.URL);
					if(url != null) {
						String path = JavaScriptDebugPlugin.findExternalScriptPathFromURI(url);
						if(path != null) {
							IFile file = (IFile) JavaScriptDebugPlugin.getExternalSourceProject(false).findMember(new Path(path));
							if(file != null && file.isAccessible()) {
								boolean isset = ((Boolean)body.get(Attributes.SET)).booleanValue();
								if(!isset) {
									
								}
								else {
									int line = -1;
									Number lineno = (Number) body.get(Attributes.LINE);
									if(lineno != null) {
										line = lineno.intValue();
									}
									if(line > -1) { 
										Map attribs = new HashMap();
										attribs.put(IJavaScriptBreakpoint.SCRIPT_PATH, body.get(Attributes.URL));
										try {
											JavaScriptDebugModel.createLineBreakpoint(file, line, -1, -1, attribs, true);
										}
										catch(DebugException de) {}
									}
								}
							}
						}
					}*/
					if(TRACE) {
						Tracing.writeString("QUEUE [event - "+CFEventPacket.ON_TOGGLE_BREAKPOINT+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
					return null;
				}
				else {
					if(TRACE) {
						Tracing.writeString("QUEUE [unknown event - "+name+"] "+JSON.serialize(event)); //$NON-NLS-1$ //$NON-NLS-2$
					}
				}
				if (set.isEmpty()) {
					set.resume();
					continue;
				}
				return set;
			}
		}
		catch(DisconnectedException de) {
			if(TRACE) {
				Tracing.writeString("QUEUE [disconnect exception]: "+de.getMessage()); //$NON-NLS-1$
			}
			crossfire().disconnectVM();
			handleException(de.getMessage(), (de.getCause() == null ? de : de.getCause()));
		}
		catch(TimeoutException te) {
			CrossFirePlugin.log(te);
		}
		return null;
	}
	
	/**
	 * Logs the entry from the queue
	 * 
	 * @param kind
	 * @param objects
	 */
	void log(int kind, List objects) {
		IStatus status = null;
		if(objects.size() > 1) {
			MultiStatus mstatus = new MultiStatus(CrossFirePlugin.PLUGIN_ID, kind, "Messages logged from Crossfire", null); //$NON-NLS-1$
			for (Iterator i = objects.iterator(); i.hasNext();) {
				mstatus.add(new Status(kind, CrossFirePlugin.PLUGIN_ID, i.next().toString()));
			}
			status = mstatus;
		}
		else if(objects.size() == 1) {
			status = new Status(kind, CrossFirePlugin.PLUGIN_ID, objects.iterator().next().toString());
		}
		if(status != null) {
			CrossFirePlugin.log(status);
		}
	}
	
	/**
	 * Handles a context created, loaded, and changed event
	 * @param set the {@link EventSet} to add to
	 * @param event the {@link CFEventPacket} received
	 * @param lookup if we should try to lookup the {@link ThreadReference} before creating a new one
	 */
	void handleContext(CFEventSet set, CFEventPacket event, boolean lookup) {
		List threads = eventmgr.threadEnterRequests();
		CFThreadReference thread = null;
		if(lookup) {
			thread = crossfire().findThread(event.getContextId());
		}
		if(thread == null) {
			thread = crossfire().addThread(event.getContextId(), (String) event.getBody().get(Attributes.HREF));
		}
		set.setThread(thread);
		for (Iterator iter = threads.iterator(); iter.hasNext();) {
			ThreadEnterRequest request = (ThreadEnterRequest) iter.next();
			set.add(new CFThreadEnterEvent(crossfire(), request, thread));
		}
	}
	
	/**
	 * Flushes and cleans up the queue
	 */
	public void dispose() {
		disposed = true;
	}
	
	/**
	 * Turns on / off tracing in the event queue
	 * @param tracing
	 */
	public static void setTracing(boolean tracing) {
		TRACE = tracing;
	}
}
