/*******************************************************************************
 * Copyright (c) 2017 Christian Pontesegger and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * Contributors:
 *     Christian Pontesegger - initial API and implementation
 *******************************************************************************/

package org.eclipse.ease.debugging;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IDebugElement;
import org.eclipse.ease.Activator;
import org.eclipse.ease.ExitException;
import org.eclipse.ease.IDebugEngine;
import org.eclipse.ease.IExecutionListener;
import org.eclipse.ease.IScriptEngine;
import org.eclipse.ease.Logger;
import org.eclipse.ease.Script;
import org.eclipse.ease.debugging.dispatcher.EventDispatchJob;
import org.eclipse.ease.debugging.dispatcher.IEventProcessor;
import org.eclipse.ease.debugging.events.AbstractEvent;
import org.eclipse.ease.debugging.events.IDebugEvent;
import org.eclipse.ease.debugging.events.debugger.EngineStartedEvent;
import org.eclipse.ease.debugging.events.debugger.EngineTerminatedEvent;
import org.eclipse.ease.debugging.events.debugger.EvaluateExpressionEvent;
import org.eclipse.ease.debugging.events.debugger.IDebuggerEvent;
import org.eclipse.ease.debugging.events.debugger.ResumedEvent;
import org.eclipse.ease.debugging.events.debugger.ScriptReadyEvent;
import org.eclipse.ease.debugging.events.debugger.StackFramesEvent;
import org.eclipse.ease.debugging.events.debugger.SuspendedEvent;
import org.eclipse.ease.debugging.events.debugger.VariablesEvent;
import org.eclipse.ease.debugging.events.model.BreakpointRequest;
import org.eclipse.ease.debugging.events.model.EvaluateExpressionRequest;
import org.eclipse.ease.debugging.events.model.GetStackFramesRequest;
import org.eclipse.ease.debugging.events.model.GetVariablesRequest;
import org.eclipse.ease.debugging.events.model.ResumeRequest;
import org.eclipse.ease.debugging.events.model.SetVariablesRequest;
import org.eclipse.ease.debugging.events.model.SuspendRequest;
import org.eclipse.ease.debugging.events.model.TerminateRequest;
import org.eclipse.ease.debugging.model.EaseDebugStackFrame;
import org.eclipse.ease.debugging.model.EaseDebugVariable;

public abstract class AbstractEaseDebugger implements IEventProcessor, IExecutionListener {

	public class ThreadState {
		/** Stacktrace is not set entirely, but incrementally updated by clients. */
		public ScriptStackTrace fStacktrace = new ScriptStackTrace();

		public ScriptStackTrace fExceptionStacktrace = null;

		public int fResumeType;

		public int fResumeLineNumber = 0;

		public boolean fSuspended = false;

		public ScriptStackTrace fResumeStack = new ScriptStackTrace();
	}

	private EventDispatchJob fDispatcher;

	private IScriptRegistry fScriptRegistry;

	private IDebugEngine fEngine;

	protected final Map<Script, List<IBreakpoint>> fBreakpoints = new HashMap<>();

	private final boolean fShowDynamicCode;

	private boolean fTerminated = false;

	private final Map<Object, ThreadState> fThreadStates = new HashMap<>();

	/** Requests to evaluate expressions. */
	private final List<AbstractEvent> fEvaluationRequests = Collections.synchronizedList(new ArrayList<>());

	public AbstractEaseDebugger(final IDebugEngine engine, final boolean showDynamicCode) {
		fEngine = engine;
		fShowDynamicCode = showDynamicCode;

		fEngine.addExecutionListener(this);
	}

	/**
	 * Protected getter for event dispatch job.
	 *
	 * @return {@link #fDispatcher}.
	 */
	protected EventDispatchJob getDispatcher() {
		return fDispatcher;
	}

	/**
	 * Setter method for dispatcher.
	 *
	 * @param dispatcher
	 *            dispatcher for communication between debugger and debug target.
	 */
	@Override
	public void setDispatcher(final EventDispatchJob dispatcher) {
		fDispatcher = dispatcher;

		// TODO: Use setScriptRegistry explicitly
		setScriptRegistry(dispatcher);
	}

	/**
	 * Setter method for script registry for lookups between different types of file identifications.
	 *
	 * @param registry
	 *            Script registry to be used.
	 */
	public void setScriptRegistry(final IScriptRegistry registry) {
		fScriptRegistry = registry;
	}

	/**
	 * Protected getter for subclasses to have access to {@link #fScriptRegistry}.
	 *
	 * @return {@link #fScriptRegistry}
	 */
	protected IScriptRegistry getScriptRegistry() {
		return fScriptRegistry;
	}

	/**
	 * Helper method to raise event via dispatcher.
	 *
	 * @param event
	 *            Debug event to be raised.
	 */
	public void fireDispatchEvent(final IDebuggerEvent event) {
		if (fDispatcher != null)
			fDispatcher.addEvent(event);
	}

	@Override
	public void handleEvent(final IDebugEvent event) {
		if (!fTerminated) {
			DebugTracer.debug("Debugger", "process " + event);

			if (event instanceof BreakpointRequest) {
				if (((BreakpointRequest) event).isRemoveAllBreakpointsRequest())
					fBreakpoints.clear();

				else {
					final Script script = ((BreakpointRequest) event).getScript();
					if (!fBreakpoints.containsKey(script))
						fBreakpoints.put(script, new ArrayList<IBreakpoint>());

					if (((BreakpointRequest) event).getMode() == BreakpointRequest.Mode.ADD) {
						final IBreakpoint breakpoint = ((BreakpointRequest) event).getBreakpoint();
						fBreakpoints.get(script).add(breakpoint);
						breakpointAdded(script, breakpoint);
					} else {
						final IBreakpoint breakpoint = ((BreakpointRequest) event).getBreakpoint();
						fBreakpoints.get(script).remove(breakpoint);
						breakpointRemoved(script, breakpoint);
					}
				}

			} else if (event instanceof SuspendRequest) {
				final ThreadState threadState = getThreadState(((AbstractEvent) event).getThread());
				threadState.fResumeType = DebugEvent.STEP_INTO;

			} else if (event instanceof TerminateRequest) {
				fEvaluationRequests.add((AbstractEvent) event);
				for (final ThreadState threadState : fThreadStates.values()) {
					synchronized (threadState) {
						threadState.notify();
					}
				}

			} else if (event instanceof AbstractEvent) {
				fEvaluationRequests.add((AbstractEvent) event);
				final ThreadState threadState = getThreadState(((AbstractEvent) event).getThread());
				synchronized (threadState) {
					threadState.notify();
				}
			}
		}
	}

	/**
	 * Callback triggered when breakpoint has been added.
	 *
	 * No-op implementations can be overridden by subclasses.
	 *
	 * @param script
	 *            Script this breakpoint belongs to.
	 * @param breakpoint
	 *            Breakpoint information.
	 */
	protected void breakpointAdded(final Script script, final IBreakpoint breakpoint) {

	}

	/**
	 * Callback triggered when breakpoint has been removed.
	 *
	 * No-op implementations can be overridden by subclasses.
	 *
	 * @param script
	 *            Script this breakpoint belonged to.
	 * @param breakpoint
	 *            Breakpoint information.
	 */
	protected void breakpointRemoved(final Script script, final IBreakpoint breakpoint) {

	}

	protected void suspend(final IDebuggerEvent event) {

		// only suspend if there possibly exists someone to wake us up again
		if (fDispatcher != null) {
			final ThreadState threadState = getThreadState(getThread());
			synchronized (threadState) {
				// need to fire event in synchronized code to avoid getting a resume event too soon
				threadState.fSuspended = true;
				fireDispatchEvent(event);

				DebugTracer.debug("Debugger", "\t engine suspended on state: " + threadState);

				try {
					while (threadState.fSuspended) {
						threadState.wait();
						// handle events after wait() as events might alter the threadState
						handleEventsInSuspendedState(threadState);
					}

				} catch (final InterruptedException e) {
					threadState.fSuspended = false;
				}

				DebugTracer.debug("Debugger", "\t engine resumed");

				fireDispatchEvent(new ResumedEvent(getThread(), getThreadState(getThread()).fResumeType));
			}
		}
	}

	private void handleEventsInSuspendedState(ThreadState threadState) {
		List<AbstractEvent> requests;
		synchronized (fEvaluationRequests) {
			requests = new ArrayList<>(fEvaluationRequests);
		}

		while (!requests.isEmpty()) {
			final AbstractEvent request = requests.remove(0);
			final ThreadState threadStateForRequest = getThreadState(request.getThread());

			if (threadState.equals(threadStateForRequest)) {

				// we handle this event, remove from queue
				fEvaluationRequests.remove(request);

				if (request instanceof EvaluateExpressionRequest) {
					try {
						final EaseDebugStackFrame scope = ((EvaluateExpressionRequest) request).getContext();
						final Object result = scope.getDebugFrame().inject(((EvaluateExpressionRequest) request).getExpression());
						fireDispatchEvent(new EvaluateExpressionEvent(((EvaluateExpressionRequest) request).getExpression(), result, null,
								((EvaluateExpressionRequest) request).getListener()));
					} catch (final Throwable e) {
						fireDispatchEvent(new EvaluateExpressionEvent(((EvaluateExpressionRequest) request).getExpression(), null, e,
								((EvaluateExpressionRequest) request).getListener()));
					}

				} else if (request instanceof GetStackFramesRequest) {
					fireDispatchEvent(new StackFramesEvent(getStacktrace(), getThread()));

				} else if (request instanceof GetVariablesRequest) {
					final EaseDebugStackFrame requestor = ((GetVariablesRequest) request).getRequestor();
					final Collection<EaseDebugVariable> variables = getEngine().getVariables(requestor.getDebugFrame());
					fireDispatchEvent(new VariablesEvent(requestor, variables));

				} else if (request instanceof SetVariablesRequest) {
					final IDebugElement requestor = ((SetVariablesRequest) request).getRequestor();
					try {
						if (requestor instanceof EaseDebugStackFrame) {

							// evaluate expression
							final Object result = getEngine().inject(((SetVariablesRequest) request).getExpression());
							// set variable
							((EaseDebugStackFrame) requestor).getDebugFrame().setVariable(((SetVariablesRequest) request).getVariable().getName(), result);

							// re-fetch variables for current stackframe
							final Collection<EaseDebugVariable> variables = getEngine().getVariables(((EaseDebugStackFrame) requestor).getDebugFrame());
							fireDispatchEvent(new VariablesEvent((EaseDebugStackFrame) requestor, variables));
						}

					} catch (final Throwable e) {
						Logger.error(Activator.PLUGIN_ID, "Could not change variable <" + ((SetVariablesRequest) request).getVariable().getName() + "> to \""
								+ ((SetVariablesRequest) request).getExpression() + "\"", e);
					}

				} else if (request instanceof ResumeRequest) {
					resume(((ResumeRequest) request).getType(), ((ResumeRequest) request).getThread());
				}
			}

			if (request instanceof TerminateRequest)
				throw new ExitException("Engine termination requested by user");
		}
	}

	protected void resume(final int resumeType, Object thread) {
		// called by engine thread

		final ThreadState threadState = fThreadStates.get(thread);

		// UNSPECIFIED is sent by the debug target if execution is resumed automatically, so stay with last user resume request
		if (resumeType != DebugEvent.UNSPECIFIED) {
			threadState.fResumeType = resumeType;
			threadState.fResumeStack = threadState.fStacktrace.clone();
			threadState.fResumeLineNumber = (threadState.fResumeStack.size() > 0) ? threadState.fStacktrace.get(0).getLineNumber() : 0;
		}

		threadState.fSuspended = false;
	}

	protected IDebugEngine getEngine() {
		return fEngine;
	}

	/**
	 * Notify function called by Eclipse EASE framework.
	 *
	 * Raises according events depending on status
	 */
	@Override
	public void notify(final IScriptEngine engine, final Script script, final int status) {
		switch (status) {
		case ENGINE_START:
			fireDispatchEvent(new EngineStartedEvent());
			break;

		case ENGINE_END:
			fireDispatchEvent(new EngineTerminatedEvent());

			// allow for garbage collection
			fTerminated = true;
			fEngine.removeExecutionListener(this);
			fEngine = null;
			fDispatcher = null;
			fThreadStates.clear();
			fBreakpoints.clear();
			break;

		case SCRIPT_START:
			// fall through
		case SCRIPT_INJECTION_START:
			// new script
			if (isTrackedScript(script))
				suspend(new ScriptReadyEvent(script, getThread(), getThreadState(getThread()).fStacktrace.isEmpty()));

			break;

		case SCRIPT_END:
			// fall through
		case SCRIPT_INJECTION_END:
			// TODO remove script from stack
			break;

		default:
			// unknown event
			break;
		}
	}

	/**
	 * Get a breakpoint for a given line in a script.
	 *
	 * @param script
	 *            script to look for
	 * @param lineNumber
	 *            line number within script to check
	 * @return {@link IBreakpoint} instance or <code>null</code>
	 */
	protected IBreakpoint getBreakpoint(final Script script, final int lineNumber) {
		final List<IBreakpoint> breakpoints = fBreakpoints.get(script);
		if (breakpoints != null) {
			for (final IBreakpoint breakpoint : breakpoints) {
				try {
					if (breakpoint.isEnabled()) {
						final int breakLocation = breakpoint.getMarker().getAttribute(IMarker.LINE_NUMBER, -1);
						if (lineNumber == breakLocation)
							return breakpoint;
					}
				} catch (final CoreException e) {
					// cannot check enabled state, ignore
				}
			}
		}

		return null;
	}

	/**
	 * Checks if the given script is tracked by debugger.
	 *
	 * @param script
	 *            Script to be checked.
	 * @return {@code true} if script is being tracked by debugger.
	 */
	public boolean isTrackedScript(final Script script) {
		return (!script.isDynamic()) || fShowDynamicCode;
	}

	/**
	 * Get current stack trace. If the current trace is empty (script not started or terminated) we get an optional exception stack trace. This is by default
	 * empty and will only be filled when an exception is thrown.
	 *
	 * @return
	 */
	public ScriptStackTrace getStacktrace() {
		return getThreadState(getThread()).fStacktrace;
	}

	protected void setStacktrace(final ScriptStackTrace stacktrace) {
		getThreadState(getThread()).fStacktrace = stacktrace;
	}

	public ScriptStackTrace getExceptionStacktrace() {
		return getExceptionStacktrace(getThread());
	}

	public ScriptStackTrace getExceptionStacktrace(Object thread) {
		return getThreadState(thread).fExceptionStacktrace;
	}

	protected void setExceptionStacktrace(final ScriptStackTrace exceptionStacktrace) {
		getThreadState(getThread()).fExceptionStacktrace = exceptionStacktrace;
	}

	protected Object getThread() {
		return Thread.currentThread();
	}

	/**
	 * Called by the debug instance on a line change. Checks for suspend conditions and suspends if necessary.
	 *
	 * @param script
	 * @param lineNumber
	 */
	protected void processLine(final Script script, final int lineNumber) {

		if (!isTrackedScript(script))
			return;

		if (lineNumber < 1)
			return;

		if (getStacktrace().isEmpty())
			return;

		DebugTracer.debug("Debugger", "\t... processing line " + script.getTitle() + ":" + lineNumber);

		final Object thread = getThread();

		// check breakpoints
		if (isActiveBreakpoint(script, lineNumber)) {
			suspend(new SuspendedEvent(DebugEvent.BREAKPOINT, thread, getStacktrace()));
			return;
		}

		// no breakpoint, check for step events
		switch (getThreadState(thread).fResumeType) {
		case DebugEvent.STEP_INTO:
			suspend(new SuspendedEvent(DebugEvent.STEP_END, thread, getStacktrace()));
			break;

		case DebugEvent.STEP_OVER:
			if (getThreadState(thread).fResumeStack.size() > getStacktrace().size()) {
				// stacktrace got smaller, we stepped out of a function or file
				if (!getStacktrace().isEmpty())
					suspend(new SuspendedEvent(DebugEvent.STEP_END, thread, getStacktrace()));

			} else if (getThreadState(thread).fResumeStack.size() == getStacktrace().size()) {
				// same stacktrace, check if line number changed
				if (getThreadState(thread).fResumeLineNumber != getStacktrace().get(0).getLineNumber())
					suspend(new SuspendedEvent(DebugEvent.STEP_END, thread, getStacktrace()));
			}

			break;

		case DebugEvent.STEP_RETURN:
			if (getThreadState(thread).fResumeStack.size() > getStacktrace().size())
				suspend(new SuspendedEvent(DebugEvent.STEP_END, thread, getStacktrace()));

			break;

		default:
			// either user did not request anything yet or "RESUME" was triggered
		}
	}

	protected boolean isActiveBreakpoint(Script script, int lineNumber) {
		final IBreakpoint breakpoint = getBreakpoint(script, lineNumber);
		return breakpoint != null;
	}

	protected ThreadState getThreadState(Object thread) {
		if (!fThreadStates.containsKey(thread))
			fThreadStates.put(thread, new ThreadState());

		return fThreadStates.get(thread);
	}
}
