/*******************************************************************************
 * Copyright (c) 2009, 2010, 2011 Nokia 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:
 * Nokia - Initial API and implementation
 *******************************************************************************/
package org.eclipse.cdt.debug.edc.internal.eval.ast.engine.instructions;

import java.text.MessageFormat;
import java.util.Collection;
import java.util.List;

import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.debug.edc.internal.EDCDebugger;
import org.eclipse.cdt.debug.edc.internal.eval.ast.engine.ASTEvalMessages;
import org.eclipse.cdt.debug.edc.internal.services.dsf.EDCSymbolReader;
import org.eclipse.cdt.debug.edc.internal.services.dsf.Modules.ModuleDMC;
import org.eclipse.cdt.debug.edc.internal.services.dsf.RunControl.ProcessExecutionDMC;
import org.eclipse.cdt.debug.edc.internal.services.dsf.RunControl.ThreadExecutionDMC;
import org.eclipse.cdt.debug.edc.internal.services.dsf.Symbols;
import org.eclipse.cdt.debug.edc.internal.symbols.InvalidVariableLocation;
import org.eclipse.cdt.debug.edc.services.EDCServicesTracker;
import org.eclipse.cdt.debug.edc.services.IEDCExecutionDMC;
import org.eclipse.cdt.debug.edc.services.IEDCModules;
import org.eclipse.cdt.debug.edc.services.Stack;
import org.eclipse.cdt.debug.edc.services.Stack.EnumeratorDMC;
import org.eclipse.cdt.debug.edc.services.Stack.IVariableEnumeratorContext;
import org.eclipse.cdt.debug.edc.services.Stack.StackFrameDMC;
import org.eclipse.cdt.debug.edc.services.Stack.VariableDMC;
import org.eclipse.cdt.debug.edc.symbols.IDebugInfoProvider;
import org.eclipse.cdt.debug.edc.symbols.IEDCSymbolReader;
import org.eclipse.cdt.debug.edc.symbols.ILocationProvider;
import org.eclipse.cdt.debug.edc.symbols.IScope;
import org.eclipse.cdt.debug.edc.symbols.IVariable;
import org.eclipse.cdt.debug.edc.symbols.IVariableLocation;
import org.eclipse.cdt.debug.edc.symbols.TypeUtils;
import org.eclipse.cdt.dsf.datamodel.DMContexts;
import org.eclipse.cdt.dsf.datamodel.IDMContext;
import org.eclipse.cdt.dsf.debug.service.IStack.IFrameDMContext;
import org.eclipse.core.runtime.CoreException;

public class EvaluateID extends SimpleInstruction {

	private String name;
	private final ICPPASTQualifiedName qualifiedName;

	/**
	 * Constructor for ID (number + variable name) evaluate instruction
	 * 
	 * @param idExpression
	 */
	public EvaluateID(IASTIdExpression idExpression) {
		IASTName lookupName;

		if (idExpression.getName() instanceof ICPPASTQualifiedName) {
			// the name has the form namespace::...::variable
			qualifiedName = (ICPPASTQualifiedName) idExpression.getName();
			lookupName = qualifiedName.getLastName();
		} else {
			lookupName = idExpression.getName();
			qualifiedName = null;
		}

		name = new String(lookupName.getLookupKey());
	}
	
	/**
	 * Constructor for lookup of a specific literal name
     * (presumably a local, like "this")
     *
     * @param name the literal name
	 */
	public EvaluateID(String name) {
		this.name = name;
		this.qualifiedName = null;
	}

	/**
	 * Resolve a variable ID
	 * 
	 * @throws CoreException
	 */
	@Override
	public void execute() throws CoreException {
		IDMContext context = getContext();

		if (!((context instanceof StackFrameDMC) || (context instanceof ModuleDMC)))
			throw EDCDebugger.newCoreException(MessageFormat.format(ASTEvalMessages.EvaluateID_CannotResolveName, name));

		EDCServicesTracker servicesTracker = null;
		ModuleDMC module = null;
		if (context instanceof ModuleDMC) {
			module = (ModuleDMC)context;
			servicesTracker = module.getEDCServicesTracker();
		} else if (context instanceof StackFrameDMC) {

			StackFrameDMC frame = (StackFrameDMC) context;
			servicesTracker = frame.getEDCServicesTracker();

			// This may be called on debugger shutdown, in which case the "modules" 
			// service may have been shutdown.
			IEDCModules modules = servicesTracker.getService(IEDCModules.class);
			if (modules == null)
				return;			

			// check by name for a variable or enumerator
			IVariableEnumeratorContext variableOrEnumerator
			  = frame.findVariableOrEnumeratorByName(name, qualifiedName != null ? qualifiedName.getRawSignature() : null, false);
			VariableDMC variable
			  = variableOrEnumerator instanceof VariableDMC ? (VariableDMC)variableOrEnumerator : null;
			EnumeratorDMC enumerator
			  = variableOrEnumerator instanceof EnumeratorDMC ? (EnumeratorDMC)variableOrEnumerator : null;

			module = (ModuleDMC)frame.getModule();
			if (variable != null) {
				IVariableLocation valueLocation = null;
				ILocationProvider provider = variable.getVariable().getLocationProvider();
				if (module != null && provider != null) {
					valueLocation = provider.getLocation(servicesTracker, frame, module.toLinkAddress(frame.getInstructionPtrAddress()),
														 TypeUtils.isConstType(variable.getVariable().getType()));
				}
				if (valueLocation == null) {
					// unhandled
					valueLocation
					  = new InvalidVariableLocation(
							  MessageFormat.format(ASTEvalMessages.EvaluateID_NameHasNoLocation,
												   variable.getName()));
				}

				// create a VariableWithValue and push on the stack
				VariableWithValue varWval = new VariableWithValue(servicesTracker, frame, variable.getVariable());
				varWval.setValueLocation(valueLocation);
				push(varWval);
				return;
			}
	
			if (enumerator != null) {
				// TODO: map IEnumerator to an IEnumeration and use the real type
				pushNewValue(fInterpreter.getTypeEngine().getIntegerTypeOfSize(4, true),
						enumerator.getEnumerator().getValue());
				return;
			}
		}

		if (module != null) {
			@SuppressWarnings("null")	// XXX false positive null-check on servicesTracker
			Symbols symbolsService = servicesTracker.getService(Symbols.class);
			if (symbolsService != null) {
				String searchName = name;
				if (qualifiedName != null)
					searchName = qualifiedName.getRawSignature();

				// first attempt to match against variable names in the module
				IEDCSymbolReader reader = module.getSymbolReader();
				if (reader instanceof EDCSymbolReader) {
					if (findGlobalVariable(searchName, (EDCSymbolReader)reader, servicesTracker)
						|| findLocalVariable(searchName, module, (EDCSymbolReader)reader, servicesTracker))
						return;
				}

				// if no variable matches, attempt to
				// match against function names visible in the module
				List<IAddress> addresses = symbolsService.getFunctionAddress(module, searchName);
				if (addresses.size() > 0) {
					pushNewValue(fInterpreter.getTypeEngine().getIntegerTypeOfSize(4, false),
								 addresses.get(0).getValue().longValue());
					return;
				}
				// show the whole qualified name in the exception message
				name = searchName;
			}
		}

		// did not find a variable, enumerator, or function to match the expression
		throw EDCDebugger.newCoreException(
				MessageFormat.format(ASTEvalMessages.EvaluateID_VariableNotFound, name));
	}

	/**
	 * @param servicesTracker
	 * @param searchName
	 * @param idip
	 * @param baseLinkAddress
	 */
	private boolean findGlobalVariable(String searchName,
			EDCSymbolReader reader, EDCServicesTracker servicesTracker) {

		IDebugInfoProvider idip = reader.getDebugInfoProvider();
		if (idip == null)
			return false;

		Collection<IVariable> vars = idip.getVariablesByName(searchName, true);
		for (IVariable var : vars) {
			IVariableLocation loc
			  = var.getLocationProvider()
				   .getLocation(servicesTracker, null, reader.getBaseLinkAddress(), 
								TypeUtils.isConstType(var.getType()));
			if (loc instanceof InvalidVariableLocation)
				continue;

			VariableWithValue varWval
			  = new VariableWithValue(servicesTracker, null, var);
			varWval.setValueLocation(loc);
			push(varWval);
			return true;
		}
		return false;
	}

	/**
	 * @param context
	 * @param servicesTracker
	 * @param searchName
	 * @param reader
	 * @param idip
	 * @throws CoreException
	 */
	private boolean findLocalVariable(String searchName, ModuleDMC module,
			EDCSymbolReader reader, EDCServicesTracker servicesTracker) {

		IDebugInfoProvider idip = reader.getDebugInfoProvider();
		if (idip == null)
			return false;

		Stack stackService = servicesTracker.getService(Stack.class);
		if (stackService == null)
			return false;

		final ProcessExecutionDMC procDMC
		  = DMContexts.getAncestorOfType(module, ProcessExecutionDMC.class);
		if (procDMC == null)
			return false;
		Collection<IVariable> vars = idip.getVariablesByName(searchName, false);
		if (vars == null || vars.isEmpty())
			return false;

		for (IEDCExecutionDMC tc : procDMC.getChildren()) { 
			if (!(tc instanceof ThreadExecutionDMC)
					|| !((ThreadExecutionDMC)tc).isSuspended())
				continue;
			IFrameDMContext[] frames;
			try {
				frames = stackService.getFramesForDMC(tc, 0, Stack.ALL_FRAMES);
			} catch (CoreException e) {
				continue;	// let's try another thread, if available
			}
			for (IFrameDMContext frame : frames)
				if (frame instanceof StackFrameDMC) {
					StackFrameDMC stackFrame = (StackFrameDMC)frame;
					IAddress pc = stackFrame.getInstructionPtrAddress();
					for (IVariable var : vars) {
						IScope varScope = var.getScope();
						if (varScope.getLowAddress().compareTo(pc) <= 0
							&& pc.compareTo(varScope.getHighAddress()) < 0) {

							VariableWithValue varWval
							  = new VariableWithValue(servicesTracker,
									  				  stackFrame, var);
							push(varWval);
							return true;
						}
					}
				}
		}
		return false;
	}
}
