/*******************************************************************************
 * Copyright (c) 2014 Kloesch 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:
 *     Kloesch - initial API and implementation
 *******************************************************************************/

package org.eclipse.ease.lang.python.debugger;

import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import org.eclipse.core.resources.IFile;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.ease.ExitException;
import org.eclipse.ease.IDebugEngine;
import org.eclipse.ease.IExecutionListener;
import org.eclipse.ease.IScriptEngine;
import org.eclipse.ease.Script;
import org.eclipse.ease.debugging.AbstractEaseDebugger;
import org.eclipse.ease.debugging.EaseDebugFrame;
import org.eclipse.ease.debugging.IScriptDebugFrame;
import org.eclipse.ease.debugging.ScriptStackTrace;
import org.eclipse.ease.debugging.dispatcher.IEventProcessor;

/**
 * Debugger class handling communication between Python and Eclipse.
 */
public class PythonDebugger extends AbstractEaseDebugger implements IEventProcessor, IExecutionListener {
	/**
	 * Variable name for {@link PythonDebugger} in Python engine. During setup phase set this variable <b>BEFORE</b> calling edb.py.
	 */
	public static final String PYTHON_DEBUGGER_VARIABLE = "_pyease_debugger";

	/**
	 * Custom {@link EaseDebugFrame} parsing the data from {@link IPyFrame} to more usable format.
	 */
	public class PythonDebugFrame extends EaseDebugFrame implements IScriptDebugFrame {
		private final IPyFrame fFrame;

		/**
		 * Constructor parses information from {@link IPyFrame} to correct parameters for {@link EaseDebugFrame#ScriptDebugFrame(Script, int, int)}.
		 *
		 * @param frame
		 *            {@link IPyFrame} with information about the current execution frame.
		 */
		public PythonDebugFrame(final IPyFrame frame) {
			super(fScriptRegistry.get(frame.getFilename()), frame.getLineNumber(), TYPE_FILE);
			fFrame = frame;

		}

		@Override
		public String getName() {
			final Script script = getScript();
			if (script.isDynamic()) {
				// dynamic script
				final String title = getScript().getTitle();
				return (title != null) ? "Dynamic: " + title : "(Dynamic)";

			} else {
				final Object command = getScript().getCommand();
				if (command != null) {
					if (command instanceof IFile)
						return ((IFile) command).getName();

					else if (command instanceof File)
						return ((File) command).getName();

					return command.toString();
				}
			}

			return "(unknown source)";
		}

		@Override
		public Map<String, Object> getVariables() {
			return fFrame.getVariables();
		}

		@Override
		public void setVariable(String name, Object content) {
			fFrame.setVariable(name, content);
		}

		@Override
		public Object inject(String expression) throws Throwable {
			return getEngine().inject(expression);
		}
	}

	/**
	 * {@link ICodeTracer} for communicating with Python implementation.
	 */
	private ICodeTracer fCodeTracer;
	private boolean fBreakpointsDisabled = false;

	/**
	 * @see AbstractEaseDebugger#AbstractScriptDebugger(IScriptEngine, boolean)
	 */
	public PythonDebugger(final IDebugEngine engine, final boolean showDynamicCode) {
		super(engine, showDynamicCode);
	}

	/**
	 * Sets the {@link ICodeTracer} from the Python implementation.
	 * <p>
	 * This method will be called by edb.py on {@value #PYTHON_DEBUGGER_VARIABLE}.
	 *
	 * @param tracer
	 *            {@link ICodeTracer} for the connection between Eclipse and Python.
	 */
	public void setCodeTracer(final ICodeTracer tracer) {
		fCodeTracer = tracer;
	}

	/**
	 * Parses given frame for its call stack.
	 *
	 * @param origin
	 *            Top frame of stack.
	 * @return Stack based on given {@link IPyFrame}
	 */
	private ScriptStackTrace getStacktrace(final IPyFrame origin) {
		final ScriptStackTrace trace = new ScriptStackTrace();

		IPyFrame frame = origin;
		while (frame != null) {
			final Script script = fScriptRegistry.get(frame.getFilename());
			if (script != null) {
				if (isTrackedScript(fScriptRegistry.get(frame.getFilename())))
					trace.add(new PythonDebugFrame(frame));
			}

			frame = frame.getParent();
		}

		return trace;
	}

	/**
	 * Function called from {@link ICodeTracer} whenever a new frame in Python is hit. Effectively checks if debugger should suspend or continue.
	 *
	 * @param frame
	 *            {@link IPyFrame} for current execution point.
	 * @param type
	 *            Type of trace step that occurred (ignored).
	 */
	public void traceDispatch(final IPyFrame frame, final String type) {
		final Script script = fScriptRegistry.get(frame.getFilename());
		if (script != null) {
			if (isTrackedScript(script)) {

				// update stacktrace
				setStacktrace(getStacktrace(frame));

				// do not process script load event (line == 0)
				if (frame.getLineNumber() != 0) {
					// do not evaluate breakpoints when returning from a function call
					fBreakpointsDisabled = "return".equals(type) || "call".equals(type);

					processLine(script, frame.getLineNumber());
				}
			}
		}
	}

	@Override
	protected boolean isActiveBreakpoint(Script script, int lineNumber) {
		if (!fBreakpointsDisabled)
			return super.isActiveBreakpoint(script, lineNumber);

		return false;
	}

	/**
	 * Runs the given {@link Script} using the {@link ICodeTracer}.
	 * <p>
	 * Return values are ignored in debug mode.
	 *
	 * @param script
	 *            Script to be executed.
	 * @return Always <code>null</code>
	 */
	public Object execute(final Script script) {
		try {
			return fCodeTracer.run(script, registerScript(script));

		} catch (final Exception e) {
			/*
			 * When terminating, #handleEvent sets resume type to STEP_END, which causes #traceDispatch to raise an ExitException. The ExitException is
			 * propagated back to python, and eventually ends up back here at Exit method. However Py4J does not support propogating the same type of exception
			 * across the Python/Java barrier, so what ends up being thrown is a Py4JException instead.
			 *
			 * Therefore we catch that case and re-raise the expected ExitException()
			 */
			if (getThreadState(getThread()).fResumeType == DebugEvent.STEP_END) {
				throw new ExitException("Debug aborted by user");
			}
			throw e;
		}
	}

	/**
	 * Map from custom filename to actual {@link Script} for easily identifying different scripts.
	 * <p>
	 * For each new file a unique filename is created using {@link #getHash(Script, Set)}.
	 */
	private final Map<String, Script> fScriptRegistry = new HashMap<>();

	private String registerScript(final Script script) {
		final String reference = getHash(script, fScriptRegistry.keySet());
		fScriptRegistry.put(reference, script);

		return reference;
	}

	/**
	 * Creates a unique filename for the given {@link Script}.
	 *
	 * @param script
	 *            {@link Script} to get unique filename for.
	 * @param existingKeys
	 *            Existing keys to avoid duplicates.
	 * @return Unique filename for given {@link Script}.
	 */
	private static String getHash(final Script script, final Set<String> existingKeys) {
		final StringBuilder buffer = new StringBuilder("__ref_");
		buffer.append(script.isDynamic() ? "dyn" : script.getCommand().toString());
		buffer.append("_");

		for (int index = 0; index < 10; index++)
			buffer.append((char) ('a' + new Random().nextInt(26)));

		if (existingKeys.contains(buffer.toString()))
			return getHash(script, existingKeys);

		return buffer.toString();
	}
}
