/*******************************************************************************
 * Copyright (c) 2009, 2011 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.rhino.debugger;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.wst.jsdt.debug.internal.rhino.transport.EventPacket;
import org.eclipse.wst.jsdt.debug.internal.rhino.transport.JSONConstants;
import org.eclipse.wst.jsdt.debug.internal.rhino.transport.JSONUtil;
import org.eclipse.wst.jsdt.debug.transport.TransportService;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.ContextFactory;
import org.mozilla.javascript.debug.DebugFrame;
import org.mozilla.javascript.debug.DebuggableScript;
import org.mozilla.javascript.debug.Debugger;

/**
 * Rhino implementation of {@link Debugger}
 * <br><br>
 * Events fired:
 * <ul>
 * <li><b>Thread enter event</b> - when a new context is created see: {@link #contextCreated(Context)}</li>
 * <li><b>Thread exit event</b> - when a context is exited see: {@link #contextReleased(Context)}</li>
 * <li><b>VM death event</b> - if the debugger dies: this event can only be received if the underlying communication channel has not been interrupted</li>
 * </ul>
 * @since 1.0
 */
public class RhinoDebuggerImpl implements Debugger, ContextFactory.Listener {

	public static final DebuggableScript[] NO_SCRIPTS = new DebuggableScript[0];
	private static final String RHINO_SCHEME = "rhino"; //$NON-NLS-1$
	
	private final Map threadToThreadId = new HashMap();
	private final Map threadIdToData = new HashMap();
	private final Map breakpoints = new HashMap();

	private long currentThreadId = 0L;
	private long currentBreakpointId = 0L;
	private long currentScriptId = 0L;
	private ArrayList disabledThreads = new ArrayList();

	/**
	 * Mapping of the URI string to the {@link ScriptSource}
	 */
	private HashMap/*<String, ScriptSource>*/ uriToScript = new HashMap();
	/**
	 * Mapping of the id to the {@link ScriptSource}
	 */
	private HashMap/*<Long, ScriptSource>*/ idToScript = new HashMap();

	private final DebugSessionManager sessionManager;
	
	/**
	 * This constructor will only accept a <code>transport</code> argument
	 * of <code>socket</code>. I.e. <code>transport=socket</code>.<br><br>
	 * 
	 * To use a differing {@link TransportService} pleas use the other constructor:
	 * {@link #RhinoDebugger(TransportService, String, boolean)}
	 * 
	 * @param configString the configuration string, for example: <code>transport=socket,suspend=y,address=9000</code>
	 */
	public RhinoDebuggerImpl(String configString) {
		sessionManager = DebugSessionManager.create(configString);
	}
	
	/**
	 * This constructor allows you to specify a custom {@link TransportService} to use other than <code>socket</code>.
	 * 
	 * @param transportService the {@link TransportService} to use for debugger communication
	 * @param address the address to communicate on
	 * @param startSuspended if the debugger should wait while accepting a connection. The wait time for stating suspended is not indefinite,
	 * @param trace if the debugger should be in tracing mode, reporting debug statements to the console 
	 * and is equal to 300000ms.
	 */
	public RhinoDebuggerImpl(TransportService transportService, String address, boolean startSuspended, boolean trace) {
		sessionManager = new DebugSessionManager( transportService,  address,  startSuspended, trace);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.mozilla.javascript.debug.Debugger#getFrame(org.mozilla.javascript.Context, org.mozilla.javascript.debug.DebuggableScript)
	 */
	public synchronized DebugFrame getFrame(Context context, DebuggableScript debuggableScript) {
		ScriptSource script = getScript(debuggableScript);
		if(script != null && !script.isStdIn()) {
			ContextData contextData = (ContextData) context.getDebuggerContextData();
			ThreadData thread = (ThreadData) threadIdToData.get(contextData.getThreadId());
			FunctionSource function = script.getFunction(debuggableScript);
			return thread.getFrame(context, function, script);
		}
		return null;
	}
	
	/**
	 * Returns the root {@link ScriptSource} context
	 * 
	 * @param script
	 * @return the root {@link ScriptSource} context
	 */
	private ScriptSource getScript(DebuggableScript script) {
		synchronized (uriToScript) {
			DebuggableScript root = script;
			while (!root.isTopLevel()) {
				root = root.getParent();
			}
			URI uri = getSourceUri(root, parseSourceProperties(root.getSourceName()));
			if(uri != null) {
				return (ScriptSource) uriToScript.get(uri);
			}
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.mozilla.javascript.debug.Debugger#handleCompilationDone(org.mozilla.javascript.Context, org.mozilla.javascript.debug.DebuggableScript, java.lang.String)
	 */
	public void handleCompilationDone(Context context, DebuggableScript script, String source) {
		if (!script.isTopLevel()) {
			return;
		}
		Map properties = parseSourceProperties(script.getSourceName());
		URI uri = getSourceUri(script, properties);
		if(uri == null) {
			//if the source cannot be located don't load or notify
			return;
		}
		final ScriptSource newscript = new ScriptSource(script, source, uri, script.isGeneratedScript(), properties);
		synchronized (uriToScript) {
			ScriptSource old = (ScriptSource) uriToScript.remove(uri);
			Long id = null;
			if(old != null) {
				//recycle the id for a re-loaded script
				//https://bugs.eclipse.org/bugs/show_bug.cgi?id=306832
				id = old.getId();
				idToScript.remove(id);
				newscript.setId(id);
				//clean up the cache of breakpoints
				old.clearBreakpoints(this);
			}
			else {
				//a totally new script is loaded
				id = scriptId();
				newscript.setId(id);
			}
			uriToScript.put(uri, newscript);
			idToScript.put(id, newscript);
		}
		ContextData contextData = (ContextData) context.getDebuggerContextData();
		contextData.scriptLoaded(newscript);
	}

	/**
	 * Composes a {@link URI} representing the path to the source of the given script
	 * 
	 * @param script the script to create a {@link URI} for
	 * @param properties any special properties @see {@link #parseSourceProperties(String)}
	 * @return the {@link URI} for the source or <code>null</code>
	 */
	private URI getSourceUri(DebuggableScript script, Map properties) {
			String sourceName = script.getSourceName();
			if(properties != null) {
				String jsonName = (String) properties.get(JSONConstants.NAME);
				if (jsonName != null)
					sourceName = jsonName;
			}
			
			// handle null sourceName
			if (sourceName == null)
				return null;
			
			// handle input from the Rhino Shell
			if (sourceName.equals("<stdin>")) { //$NON-NLS-1$
				sourceName = "stdin"; //$NON-NLS-1$
			} 
			if(sourceName.equals("<command>")) { //$NON-NLS-1$
				sourceName = "command"; //$NON-NLS-1$
			}
			else {	
				// try to parse it as a file
				File sourceFile = new File(sourceName);
				if (sourceFile.exists())
					return sourceFile.toURI();
				
				//try to just create a URI from the name
				try {
					return new URI(sourceName);
				} catch(URISyntaxException e) {
					//do nothing and fall through
				}
			}
			
			//fall back to creating a rhino specific URI from the script source name as a path
			try {
				if (! (sourceName.charAt(0) == '/'))
					sourceName = "/" + sourceName; //$NON-NLS-1$
				return new URI(RHINO_SCHEME, null, sourceName, null);
			} catch (URISyntaxException e) {
				return null;
			}
	}
	
	/**
	 * Returns any special properties specified in the source name or <code>null</code>
	 * 
	 * @param sourceName
	 * @return any special properties specified in the source name or <code>null</code>
	 */
	Map parseSourceProperties(String sourceName) {
		if (sourceName != null && sourceName.charAt(0) == '{') {
			try {
				Object json = JSONUtil.read(sourceName);
				if (json instanceof Map) {
					return (Map) json;
				}
			} catch (RuntimeException e) {
				// ignore
			}
		}
		return null;
	}
	
	/**
	 * Returns the next script id to use
	 * 
	 * @return the next id
	 */
	synchronized Long scriptId() {
		return new Long(currentScriptId++);
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.mozilla.javascript.ContextFactory.Listener#contextCreated(org.mozilla.javascript.Context)
	 */
	public synchronized void contextCreated(Context context) {
		Thread thread = Thread.currentThread();
		if (disabledThreads.contains(thread)) {
			return;
		}
		Long threadId = (Long) threadToThreadId.get(thread);
		if (threadId == null) {
			threadId = new Long(currentThreadId++);
			threadToThreadId.put(thread, threadId);
		}
		ThreadData threadData = (ThreadData) threadIdToData.get(threadId);
		if (threadData == null) {
			threadData = new ThreadData(threadId, this);
			threadIdToData.put(threadId, threadData);
			sendThreadEvent(JSONConstants.ENTER, threadId);
		}
		threadData.contextCreated(context);
	}

	/**
	 * Sends a thread event for the given type
	 * 
	 * @param type the type of event to send
	 * @param threadId the id of the thread the even is for
	 * 
	 * @see JSONConstants#ENTER
	 * @see JSONConstants#EXIT
	 */
	private void sendThreadEvent(String type, Long threadId) {
		EventPacket threadEvent = new EventPacket(JSONConstants.THREAD);
		Map body = threadEvent.getBody();
		body.put(JSONConstants.TYPE, type);
		body.put(JSONConstants.THREAD_ID, threadId);
		sendEvent(threadEvent);
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see org.mozilla.javascript.ContextFactory.Listener#contextReleased(org.mozilla.javascript.Context)
	 */
	public synchronized void contextReleased(Context context) {
		Thread thread = Thread.currentThread();
		if (disabledThreads.contains(thread)) {
			return;
		}
		Long threadId = (Long) threadToThreadId.get(thread);
		if (threadId == null) {
			return;
		}
		ThreadData threadData = (ThreadData) threadIdToData.get(threadId);
		threadData.contextReleased(context);
		if (!threadData.hasContext()) {
			threadToThreadId.remove(thread);
			threadIdToData.remove(threadId);
			sendThreadEvent(JSONConstants.EXIT, threadId);
		}
	}

	/**
	 * Resumes a thread with the given id for the given step type. Has no effect if no such thread exists
	 * 
	 * @param threadId
	 * @param stepType
	 */
	public synchronized void resume(Long threadId, String stepType) {
		ThreadData threadData = (ThreadData) threadIdToData.get(threadId);
		if (threadData != null) {
			threadData.resume(stepType);
		}
	}

	/**
	 * Resumes all threads currently in the debugger
	 */
	public synchronized void resumeAll() {
		for (Iterator it = threadIdToData.keySet().iterator(); it.hasNext();) {
			Long threadId = (Long) it.next();
			resume(threadId, null);
		}
	}

	/**
	 * Suspend the thread with the given id. Has no effect if no such thread exists
	 * 
	 * @param threadId
	 */
	public synchronized void suspend(Long threadId) {
		ThreadData threadData = (ThreadData) threadIdToData.get(threadId);
		if (threadData != null) {
			threadData.suspend();
		}
	}

	/**
	 * Suspend all threads currently in the debugger
	 */
	public synchronized void suspendAll() {
		for (Iterator it = threadIdToData.keySet().iterator(); it.hasNext();) {
			Long threadId = (Long) it.next();
			suspend(threadId);
		}
	}

	/**
	 * Disconnects the debugger
	 */
	public void disconnect() {
	}

	/**
	 * Returns all of the stack frame ids for the thread with the given id. Returns an empty list if no such thread exists, never <code>null</code>
	 * 
	 * @param threadId
	 * @return the complete list of stack frame ids from the thread with the given id
	 */
	public synchronized List getFrameIds(Long threadId) {
		ThreadData threadData = (ThreadData) threadIdToData.get(threadId);
		if (threadData == null) {
			return Collections.EMPTY_LIST;
		}
		return threadData.getFrameIds();
	}

	/**
	 * Returns a {@link DebugFrame} with the given id from the thread with the given thread id. Returns <code>null</code> if the no such thread exists with the given id and / or no such {@link DebugFrame} exists with the given id
	 * 
	 * @param threadId
	 * @param frameId
	 * @return the {@link DebugFrame} with the given id from the thread with the given id
	 */
	public synchronized StackFrame getFrame(Long threadId, Long frameId) {
		ThreadData threadData = (ThreadData) threadIdToData.get(threadId);
		if (threadData != null) {
			return threadData.getFrame(frameId);
		}
		return null;
	}

	/**
	 * @return the ids of all of the scripts currently known to the debugger
	 */
	public synchronized List getScriptIds() {
		return new ArrayList(idToScript.keySet());
	}

	/**
	 * Returns the script with the given id or <code>null</code> if no such script exists with the given id
	 * 
	 * @param scriptId
	 * @return the script with the given id or <code>null</code>
	 */
	public synchronized ScriptSource getScript(Long scriptId) {
		return (ScriptSource) idToScript.get(scriptId);
	}

	/**
	 * @return the complete collection of breakpoints currently known to the debugger
	 */
	public synchronized Collection getBreakpoints() {
		return breakpoints.keySet();
	}

	/**
	 * Creates a breakpoint in the script with the given id and the given breakpoint attributes. 
	 * Returns the new breakpoint or <code>null</code> if:
	 * <ul>
	 * <li>no such script exists with the given id</li>
	 * <li>the given line number is not a valid line number</li>
	 * </ul>
	 * <p>
	 * If a breakpoint already exists at the given location it is removed and the new breakpoint is set.
	 * </p>
	 * @param scriptId
	 * @param lineNumber
	 * @param functionName
	 * @param condition
	 * @param threadId
	 * @return the new breakpoint or <code>null</code> if no script exists with the given id
	 */
	public synchronized Breakpoint setBreakpoint(Long scriptId, Integer lineNumber, String functionName, String condition, Long threadId) {
		ScriptSource script = (ScriptSource) idToScript.get(scriptId);
		if (script == null || !script.isValid(lineNumber, functionName)) {
			return null;
		}

		
		Breakpoint newbreakpoint = new Breakpoint(nextBreakpointId(), script, lineNumber, functionName, condition, threadId);
		Breakpoint oldbp = script.getBreakpoint(lineNumber, functionName);
		if(oldbp != null) {
			breakpoints.remove(oldbp.breakpointId);
		}
		breakpoints.put(newbreakpoint.breakpointId, newbreakpoint);
		script.addBreakpoint(newbreakpoint);
		return newbreakpoint;
	}

	/**
	 * @return the next unique breakpoint id to use
	 */
	private synchronized Long nextBreakpointId() {
		return new Long(currentBreakpointId++);
	}

	/**
	 * Clears the breakpoint out of the cache with the given id and returns it. Returns <code>null</code> if no breakpoint exists with the given id.
	 * 
	 * @param breakpointId
	 * @return the removed breakpoint or <code>null</code>
	 */
	public synchronized Breakpoint clearBreakpoint(Long breakpointId) {
		Breakpoint breakpoint = (Breakpoint) breakpoints.remove(breakpointId);
		if (breakpoint != null) {
			breakpoint.delete();
		}
		return breakpoint;
	}

	/**
	 * Sends the given {@link EventPacket} using the underlying {@link DebugRuntime} and returns if it was sent successfully
	 * 
	 * @param event
	 * @return true if the event was sent successfully, false otherwise
	 */
	public boolean sendEvent(EventPacket event) {
		return sessionManager.sendEvent(event);
	}

	/**
	 * Gets a breakpoint with the given id, returns <code>null</code> if no such breakpoint exists with the given id
	 * 
	 * @param breakpointId
	 * @return the breakpoint with the given id or <code>null</code>
	 */
	public Breakpoint getBreakpoint(Long breakpointId) {
		return (Breakpoint) breakpoints.get(breakpointId);
	}

	/**
	 * Gets the thread for the thread with the given id, returns <code>null</code> if no such thread exists with the given id
	 * 
	 * @param threadId
	 * @return the thread data for the thread with the given id or <code>null</code>
	 */
	public synchronized ThreadData getThreadData(Long threadId) {
		return (ThreadData) threadIdToData.get(threadId);
	}

	/**
	 * @return the complete list of thread ids known to the debugger
	 */
	public synchronized List getThreadIds() {
		return new ArrayList(threadIdToData.keySet());
	}

	/**
	 * Caches the current thread as disabled
	 */
	public synchronized void disableThread() {
		disabledThreads.add(Thread.currentThread());
	}

	/**
	 * Removes the current thread as being disabled
	 */
	public synchronized void enableThread() {
		disabledThreads.remove(Thread.currentThread());
	}

	public void start() {
		sessionManager.start(this);
	}

	public void stop() {
		sessionManager.stop();
	}
	
	/**
	 * Returns if a {@link DebugSession} has successfully connected to this debugger.
	 * 
	 * @return <code>true</code> if the debugger has a connected {@link DebugSession} <code>false</code> otherwise
	 */
	public boolean isConnected() {
		return sessionManager.isConnected();
	}
}
