/*******************************************************************************
 * Copyright (c) 2005, 2018 IBM Corporation and others.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 *******************************************************************************/
package org.eclipse.dltk.internal.debug.core.model;

import java.net.URI;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IRegisterGroup;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.dltk.core.DLTKCore;
import org.eclipse.dltk.dbgp.IDbgpProperty;
import org.eclipse.dltk.dbgp.IDbgpStackLevel;
import org.eclipse.dltk.dbgp.commands.IDbgpContextCommands;
import org.eclipse.dltk.dbgp.exceptions.DbgpDebuggingEngineException;
import org.eclipse.dltk.dbgp.exceptions.DbgpException;
import org.eclipse.dltk.debug.core.DLTKDebugPlugin;
import org.eclipse.dltk.debug.core.IScriptVariableContainer;
import org.eclipse.dltk.debug.core.ScriptDebugManager;
import org.eclipse.dltk.debug.core.model.IRefreshableScriptVariable;
import org.eclipse.dltk.debug.core.model.IScriptStack;
import org.eclipse.dltk.debug.core.model.IScriptStackFrame;
import org.eclipse.dltk.debug.core.model.IScriptThread;
import org.eclipse.dltk.debug.core.model.IScriptVariable;
import org.eclipse.dltk.debug.core.model.ISourceOffsetLookup;
import org.eclipse.osgi.util.NLS;

public class ScriptStackFrame extends ScriptDebugElement
		implements IScriptStackFrame {

	private final IScriptThread thread;
	private IDbgpStackLevel level;
	private final IScriptStack stack;

	private ScriptVariableContainer variables = null;
	private boolean needRefreshVariables = false;

	protected static IScriptVariable[] readVariables(
			ScriptStackFrame parentFrame, int contextId,
			IDbgpContextCommands commands) throws DbgpException {

		try {
			IDbgpProperty[] properties = commands
					.getContextProperties(parentFrame.getLevel(), contextId);

			IScriptVariable[] variables = new IScriptVariable[properties.length];

			// Workaround for bug 215215
			// https://bugs.eclipse.org/bugs/show_bug.cgi?id=215215
			// Remove this code when Tcl active state debugger fixed
			Set<String> duplicates = findDuplicateNames(properties);

			for (int i = 0; i < properties.length; ++i) {
				IDbgpProperty property = properties[i];
				String name = property.getName();
				if (duplicates.contains(name)) {
					name = property.getEvalName();
				}
				variables[i] = new ScriptVariable(parentFrame, name, property);
			}

			return variables;
		} catch (DbgpDebuggingEngineException e) {
			if (DLTKCore.DEBUG) {
				e.printStackTrace();
			}
			return new IScriptVariable[0];
		}
	}

	private static Set<String> findDuplicateNames(IDbgpProperty[] properties) {
		final Set<String> duplicates = new HashSet<>();
		final Set<String> alreadyExsisting = new HashSet<>();
		for (int i = 0; i < properties.length; ++i) {
			final IDbgpProperty property = properties[i];
			final String name = property.getName();
			if (!alreadyExsisting.add(name)) {
				duplicates.add(name);
			}
		}
		return duplicates;
	}

	/**
	 * Return null in case suspend more is no more active during calculation of
	 * variables.
	 *
	 * @return
	 * @throws DbgpException
	 */
	protected ScriptVariableContainer readAllVariables() throws DbgpException {
		final IDbgpContextCommands commands = thread.getDbgpSession()
				.getCoreCommands();

		// TODO: Until more sequence approach will be implemented
		if (!thread.isSuspended()) {
			return null;
		}

		final ScriptVariableContainer result = new ScriptVariableContainer();

		final Map names = commands.getContextNames(getLevel());
		if (thread.retrieveLocalVariables()
				&& names.containsKey(
						Integer.valueOf(IDbgpContextCommands.LOCAL_CONTEXT_ID))
				&& thread.isSuspended()) {
			result.locals = readVariables(this,
					IDbgpContextCommands.LOCAL_CONTEXT_ID, commands);
		}
		if (thread.retrieveGlobalVariables()
				&& names.containsKey(
						Integer.valueOf(IDbgpContextCommands.GLOBAL_CONTEXT_ID))
				&& thread.isSuspended()) {
			result.globals = readVariables(this,
					IDbgpContextCommands.GLOBAL_CONTEXT_ID, commands);
		}
		if (thread.retrieveClassVariables()
				&& names.containsKey(
						Integer.valueOf(IDbgpContextCommands.CLASS_CONTEXT_ID))
				&& thread.isSuspended()) {
			result.classes = readVariables(this,
					IDbgpContextCommands.CLASS_CONTEXT_ID, commands);
		}
		// TODO: Until more sequence approach will be implemented
		if (!thread.isSuspended()) {
			return null;
		}
		return result;
	}

	private static class ScriptVariableContainer {
		IVariable[] locals = null;
		IVariable[] globals = null;
		IVariable[] classes = null;
		ScriptVariableWrapper globalsWrapper = null;
		ScriptVariableWrapper classesWrapper = null;

		ScriptVariableContainer sort(IDebugTarget target) {
			final Comparator variableComparator = ScriptDebugManager
					.getInstance().getVariableNameComparatorByDebugModel(
							target.getModelIdentifier());
			if (locals != null) {
				Arrays.sort(locals, variableComparator);
			}
			if (globals != null) {
				Arrays.sort(globals, variableComparator);
			}
			if (classes != null) {
				Arrays.sort(classes, variableComparator);
			}
			return this;
		}

		private int size() {
			int size = 0;
			if (locals != null) {
				size += locals.length;
			}
			if (globals != null) {
				++size;
			}
			if (classes != null) {
				++size;
			}
			return size;
		}

		IScriptVariable[] toArray(IDebugTarget target) {
			final int size = size();
			final IScriptVariable[] result = new IScriptVariable[size];
			if (size != 0) {
				int index = 0;
				if (globals != null) {
					if (globalsWrapper == null) {
						globalsWrapper = new ScriptVariableWrapper(target,
								Messages.ScriptStackFrame_globalVariables,
								globals,
								IScriptVariableContainer.ContainerKind.Global);
					} else {
						globalsWrapper.refreshValue(globals);
					}
					result[index++] = globalsWrapper;
				}
				if (classes != null) {
					if (classesWrapper == null) {
						classesWrapper = new ScriptVariableWrapper(target,
								Messages.ScriptStackFrame_classVariables,
								classes,
								IScriptVariableContainer.ContainerKind.Class);
					} else {
						classesWrapper.refreshValue(classes);
					}
					result[index++] = classesWrapper;
				}
				if (locals != null) {
					System.arraycopy(locals, 0, result, index, locals.length);
					index += locals.length;
				}
			}
			return result;
		}

		/**
		 * @return
		 */
		public boolean hasVariables() {
			return locals != null && locals.length != 0 || classes != null
					|| globals != null;
		}

		/**
		 * @param varName
		 * @return
		 * @throws DebugException
		 */
		public IVariable findVariable(String varName) throws DebugException {
			if (locals != null) {
				final IVariable variable = findVariable(varName, locals);
				if (variable != null) {
					return variable;
				}
			}
			if (globals != null) {
				final IVariable variable = findVariable(varName, globals);
				if (variable != null) {
					return variable;
				}
			}
			return null;
		}

		private static IVariable findVariable(String varName, IVariable[] vars)
				throws DebugException {
			for (int i = 0; i < vars.length; i++) {
				final IVariable var = vars[i];
				if (var.getName().equals(varName)) {
					return var;
				}
			}
			return null;
		}
	}

	public ScriptStackFrame(IScriptStack stack, IDbgpStackLevel stackLevel) {
		this.stack = stack;
		this.thread = stack.getThread();
		this.level = stackLevel;
	}

	public synchronized void updateVariables() {
		this.variables = null;
	}

	@Override
	public IScriptStack getStack() {
		return stack;
	}

	private static final int MULTI_LINE_COUNT = 2;

	@Override
	public int getCharStart() throws DebugException {
		final int beginLine = level.getBeginLine();
		if (beginLine > 0) {
			final int endLine = level.getEndLine();
			if (endLine > 0 && endLine >= beginLine) {
				final ISourceOffsetLookup offsetLookup = DLTKDebugPlugin
						.getSourceOffsetLookup();
				if (offsetLookup != null) {
					return offsetLookup.calculateOffset(this, beginLine,
							level.getBeginColumn(), false);
				}
			}
		}
		return -1;
	}

	@Override
	public int getCharEnd() throws DebugException {
		final int endLine = level.getEndLine();
		if (endLine > 0) {
			final int beginLine = level.getBeginLine();
			if (beginLine > 0 && endLine >= beginLine) {
				final ISourceOffsetLookup offsetLookup = DLTKDebugPlugin
						.getSourceOffsetLookup();
				if (offsetLookup != null) {
					if (endLine < beginLine + MULTI_LINE_COUNT) {
						final int offset = offsetLookup.calculateOffset(this,
								endLine, level.getEndColumn(), true);
						if (offset >= 0) {
							return offset + 1;
						}
					} else {
						final int offset = offsetLookup.calculateOffset(this,
								beginLine, -1, true);
						if (offset >= 0) {
							return offset + 1;
						}
					}
				}
			}
		}
		return -1;
	}

	@Override
	public int getLineNumber() {
		return level.getLineNumber();
	}

	@Override
	public int getMethodOffset() {
		return level.getMethodOffset();
	}

	@Override
	public String getMethodName() {
		return level.getMethodName();
	}

	@Override
	public int getBeginLine() {
		return level.getBeginLine();
	}

	@Override
	public int getBeginColumn() {
		return level.getBeginColumn();
	}

	@Override
	public int getEndLine() {
		return level.getEndLine();
	}

	@Override
	public int getEndColumn() {
		return level.getEndColumn();
	}

	@Override
	public String getWhere() {
		return level.getWhere().trim();
	}

	@Override
	public String getName() throws DebugException {
		String name = level.getWhere().trim();

		if (name == null || name.length() == 0) {
			name = toString();
		}

		name += " (" + level.getFileURI().getPath() + ")"; //$NON-NLS-1$ //$NON-NLS-2$

		return name;
	}

	@Override
	public boolean hasRegisterGroups() throws DebugException {
		return false;
	}

	@Override
	public IRegisterGroup[] getRegisterGroups() throws DebugException {
		return new IRegisterGroup[0];
	}

	@Override
	public IThread getThread() {
		return thread;
	}

	@Override
	public synchronized boolean hasVariables() throws DebugException {
		checkVariablesAvailable();
		if (variables == null) {
			return false;
		}
		return variables.hasVariables();
	}

	private synchronized void checkVariablesAvailable() throws DebugException {
		if (!thread.isSuspended()) {
			// Do not do variables lookup if not suspended, since it could
			// become in running/stepping state until we get here.
			return;
		}
		try {
			if (variables == null) {
				variables = readAllVariables();
				if (variables != null) {
					variables.sort(getDebugTarget());
				}
			} else if (needRefreshVariables) {
				try {
					refreshVariables();
				} finally {
					needRefreshVariables = false;
				}
			}
		} catch (DbgpException e) {
			variables = new ScriptVariableContainer();
			final Status status = new Status(IStatus.ERROR,
					DLTKDebugPlugin.PLUGIN_ID,
					Messages.ScriptStackFrame_unableToLoadVariables, e);
			DLTKDebugPlugin.log(status);
			throw new DebugException(status);
		}
	}

	/**
	 * @throws DebugException
	 * @throws DbgpException
	 */
	private void refreshVariables() throws DebugException, DbgpException {
		final ScriptVariableContainer newVars = readAllVariables();
		if (newVars == null) {
			// No need to refresh, refresh will happen in next
			variables = null;
			return;
		}
		newVars.sort(getDebugTarget());
		variables.locals = refreshVariables(newVars.locals, variables.locals);
		variables.globals = refreshVariables(newVars.globals,
				variables.globals);
		variables.classes = refreshVariables(newVars.classes,
				variables.classes);
	}

	/**
	 * @param newVars
	 * @param oldVars
	 * @return
	 * @throws DebugException
	 */
	static IVariable[] refreshVariables(IVariable[] newVars,
			IVariable[] oldVars) throws DebugException {
		if (oldVars != null) {
			final Map<String, IVariable> map = new HashMap<>();
			for (int i = 0; i < oldVars.length; ++i) {
				final IVariable variable = oldVars[i];
				if (variable instanceof IRefreshableScriptVariable) {
					map.put(variable.getName(), variable);
				}
			}
			if (newVars != null) {
				for (int i = 0; i < newVars.length; ++i) {
					final IVariable variable = newVars[i];
					final IRefreshableScriptVariable old;
					old = (IRefreshableScriptVariable) map
							.get(variable.getName());
					if (old != null) {
						newVars[i] = old.refreshVariable(variable);
					}
				}
			}
		}
		return newVars;
	}

	@Override
	public synchronized IVariable[] getVariables() throws DebugException {
		checkVariablesAvailable();
		if (variables != null) {
			return variables.toArray(getDebugTarget());
		}
		return new IVariable[0];
	}

	// IStep
	@Override
	public boolean canStepInto() {
		return thread.canStepInto();
	}

	@Override
	public boolean canStepOver() {
		return thread.canStepOver();
	}

	@Override
	public boolean canStepReturn() {
		return thread.canStepReturn();
	}

	@Override
	public boolean isStepping() {
		return thread.isStepping();
	}

	@Override
	public void stepInto() throws DebugException {
		thread.stepInto();
	}

	@Override
	public void stepOver() throws DebugException {
		thread.stepOver();
	}

	@Override
	public void stepReturn() throws DebugException {
		thread.stepReturn();
	}

	// ISuspenResume
	@Override
	public boolean canResume() {
		return thread.canResume();
	}

	@Override
	public boolean canSuspend() {
		return thread.canSuspend();
	}

	@Override
	public boolean isSuspended() {
		return thread.isSuspended();
	}

	@Override
	public void resume() throws DebugException {
		thread.resume();
	}

	@Override
	public void suspend() throws DebugException {
		thread.suspend();
	}

	// ITerminate
	@Override
	public boolean canTerminate() {
		return thread.canTerminate();
	}

	@Override
	public boolean isTerminated() {
		return thread.isTerminated();
	}

	@Override
	public void terminate() throws DebugException {
		thread.terminate();
	}

	// IDebugElement
	@Override
	public IDebugTarget getDebugTarget() {
		return thread.getDebugTarget();
	}

	@Override
	public synchronized IScriptVariable findVariable(String varName)
			throws DebugException {
		checkVariablesAvailable();
		if (variables != null) {
			return (IScriptVariable) variables.findVariable(varName);
		}
		return null;
	}

	@Override
	public int getLevel() {
		return level.getLevel();
	}

	@Override
	public String toString() {
		return NLS.bind(Messages.ScriptStackFrame_stackFrame,
				Integer.valueOf(level.getLevel()));
	}

	@Override
	public String getSourceLine() {
		return level.getWhere();
	}

	@Override
	public URI getSourceURI() {
		return level.getFileURI();
	}

	@Override
	public IScriptThread getScriptThread() {
		return (IScriptThread) getThread();
	}

	/**
	 * @param frame
	 * @param depth
	 * @return
	 */
	public ScriptStackFrame bind(IDbgpStackLevel newLevel) {
		if (level.isSameMethod(newLevel)) {
			level = newLevel;
			needRefreshVariables = true;
			return this;
		}
		return new ScriptStackFrame(stack, newLevel);
	}
}
