/*
 * (c) Copyright QNX Software Systems Ltd. 2002.
 * All Rights Reserved.
 *
 */
package org.eclipse.cdt.debug.mi.core.cdi.model;

import org.eclipse.cdt.debug.core.cdi.CDIException;
import org.eclipse.cdt.debug.core.cdi.ICDIExpressionManager;
import org.eclipse.cdt.debug.core.cdi.ICDIRegisterManager;
import org.eclipse.cdt.debug.core.cdi.ICDIVariableManager;
import org.eclipse.cdt.debug.core.cdi.model.ICDIStackFrame;
import org.eclipse.cdt.debug.core.cdi.model.ICDITarget;
import org.eclipse.cdt.debug.core.cdi.model.ICDIValue;
import org.eclipse.cdt.debug.core.cdi.model.ICDIVariable;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIArrayType;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIBoolType;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDICharType;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIDoubleType;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIEnumType;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIFloatType;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIFunctionType;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIIntType;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDILongLongType;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDILongType;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIPointerType;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIReferenceType;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIShortType;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIStructType;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIType;
import org.eclipse.cdt.debug.core.cdi.model.type.ICDIWCharType;
import org.eclipse.cdt.debug.mi.core.MIException;
import org.eclipse.cdt.debug.mi.core.MISession;
import org.eclipse.cdt.debug.mi.core.cdi.Format;
import org.eclipse.cdt.debug.mi.core.cdi.MI2CDIException;
import org.eclipse.cdt.debug.mi.core.cdi.Session;
import org.eclipse.cdt.debug.mi.core.cdi.model.type.ArrayValue;
import org.eclipse.cdt.debug.mi.core.cdi.model.type.BoolValue;
import org.eclipse.cdt.debug.mi.core.cdi.model.type.CharValue;
import org.eclipse.cdt.debug.mi.core.cdi.model.type.DoubleValue;
import org.eclipse.cdt.debug.mi.core.cdi.model.type.EnumValue;
import org.eclipse.cdt.debug.mi.core.cdi.model.type.FloatValue;
import org.eclipse.cdt.debug.mi.core.cdi.model.type.FunctionValue;
import org.eclipse.cdt.debug.mi.core.cdi.model.type.IntValue;
import org.eclipse.cdt.debug.mi.core.cdi.model.type.LongLongValue;
import org.eclipse.cdt.debug.mi.core.cdi.model.type.LongValue;
import org.eclipse.cdt.debug.mi.core.cdi.model.type.PointerValue;
import org.eclipse.cdt.debug.mi.core.cdi.model.type.ReferenceValue;
import org.eclipse.cdt.debug.mi.core.cdi.model.type.ShortValue;
import org.eclipse.cdt.debug.mi.core.cdi.model.type.StructValue;
import org.eclipse.cdt.debug.mi.core.cdi.model.type.WCharValue;
import org.eclipse.cdt.debug.mi.core.command.CommandFactory;
import org.eclipse.cdt.debug.mi.core.command.MIVarAssign;
import org.eclipse.cdt.debug.mi.core.command.MIVarInfoExpression;
import org.eclipse.cdt.debug.mi.core.command.MIVarListChildren;
import org.eclipse.cdt.debug.mi.core.command.MIVarSetFormat;
import org.eclipse.cdt.debug.mi.core.command.MIVarShowAttributes;
import org.eclipse.cdt.debug.mi.core.event.MIVarChangedEvent;
import org.eclipse.cdt.debug.mi.core.output.MIInfo;
import org.eclipse.cdt.debug.mi.core.output.MIVar;
import org.eclipse.cdt.debug.mi.core.output.MIVarInfoExpressionInfo;
import org.eclipse.cdt.debug.mi.core.output.MIVarListChildrenInfo;
import org.eclipse.cdt.debug.mi.core.output.MIVarShowAttributesInfo;

/**
 */
public class Variable extends VariableObject implements ICDIVariable {

	MIVar miVar;
	Value value;
	ICDIVariable[] children = new ICDIVariable[0];
	String editable = null;
	String language;
	boolean isFake = false;

	public Variable(VariableObject obj, MIVar v) {
		super(obj);
		miVar = v;
	}

	public Variable(ICDITarget target, String n, String q, ICDIStackFrame stack, int pos, int depth, MIVar v) {
		super(target, n, q, stack, pos, depth);
		miVar = v;
	}

	public MIVar getMIVar() {
		return miVar;
	}

	public Variable getChild(String name) {
		for (int i = 0; i < children.length; i++) {
			Variable variable = (Variable) children[i];
			if (name.equals(variable.getMIVar().getVarName())) {
				return variable;
			} else {
				// Look also in the grandchildren.
				Variable grandChild = variable.getChild(name);
				if (grandChild != null) {
					return grandChild;
				}
			}
		}
		return null;
	}

	String getLanguage() throws CDIException {
		if (language == null) {
			Session session = (Session) (getTarget().getSession());
			MISession mi = session.getMISession();
			CommandFactory factory = mi.getCommandFactory();
			MIVarInfoExpression var = factory.createMIVarInfoExpression(getMIVar().getVarName());
			try {
				mi.postCommand(var);
				MIVarInfoExpressionInfo info = var.getMIVarInfoExpressionInfo();
				if (info == null) {
					throw new CDIException("No answer");
				}
				language = info.getLanguage();
			} catch (MIException e) {
				throw new MI2CDIException(e);
			}
		}
		return (language == null) ? "" : language;
	}

	boolean isCPPLanguage() throws CDIException {
		return getLanguage().equalsIgnoreCase("C++");
	}

	void setIsFake(boolean f) {
		isFake = f;
	}

	boolean isFake() {
		return isFake;
	}

	public ICDIVariable[] getChildren() throws CDIException {
		// Use the default timeout.
		return getChildren(-1);
	}

	/**
	 * This can be a potentially long operation for GDB.
	 * allow the override of the timeout.
	 */
	public ICDIVariable[] getChildren(int timeout) throws CDIException {
		Session session = (Session) (getTarget().getSession());
		MISession mi = session.getMISession();
		CommandFactory factory = mi.getCommandFactory();
		MIVarListChildren var = factory.createMIVarListChildren(getMIVar().getVarName());
		try {
			if (timeout >= 0) {
				mi.postCommand(var, timeout);
			} else {
				mi.postCommand(var);
			}
			MIVarListChildrenInfo info = var.getMIVarListChildrenInfo();
			if (info == null) {
				throw new CDIException("No answer");
			}
			MIVar[] vars = info.getMIVars();
			children = new Variable[vars.length];
			for (int i = 0; i < vars.length; i++) {
				String fn= getFullName();
				String childName = vars[i].getExp();
				String childTypename = null;
				boolean childFake = false;
				ICDIType t = getType();
				if (t instanceof ICDIArrayType) {
					fn = "(" + fn + ")[" + i + "]";
					// For Array gdb varobj only return the index, override here.
					int index = castingIndex + i;
					childName = getName() + "[" + index + "]";
				} else if (t instanceof ICDIPointerType) {
					fn = "*(" + fn + ")";
				} else if (t instanceof ICDIStructType) {
					if (isCPPLanguage()) {
						// For C++ in GDB the children of the
						// the struture are the scope and the inherited classes.
						// For example:
						// class foo: public bar {
						//   int x;
						//   public: int y;
						// } foobar;
						// This will map to
						// - foobar
						//    + bar
						//    - private
						//       - x
						//    - public
						//       - y
						// So we choose to ignore the first set of children
						// but carry over to those "fake" variables the typename and the qualified name
						if (!isFake()
							|| (isFake() && !(name.equals("private") || name.equals("public") || name.equals("protected")))) {
							childFake = true;
							childTypename = getTypeName();
						} else {
							fn = "(" + fn + ")." + vars[i].getExp();
						}
					} else { // If not C++ language
						fn = "(" + fn + ")." + vars[i].getExp();
					}
				}
				Variable v = new Variable(getTarget(), childName, fn, getStackFrame(), getPosition(), getStackDepth(), vars[i]);
				if (childTypename != null) {
					// Hack to reset the typename to a known value
					v.typename = childTypename;
				}
				v.setIsFake(childFake);
				children[i] = v;
			}
		} catch (MIException e) {
			throw new MI2CDIException(e);
		}
		return children;
	}

	public int getChildrenNumber() throws CDIException {
		return miVar.getNumChild();
	}

	/**
	 * We overload the VariableObject since the gdb-varobject already knows
	 * the type and its probably more accurate.
	 * 
	 * @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariableObject#getTypeName()
	 */
	public String getTypeName() throws CDIException {
		// We overload here not to use the whatis command.
		if (typename == null) {
			typename = miVar.getType();
		}
		return typename;
	}

	/**
	 * @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#getValue()
	 */
	public ICDIValue getValue() throws CDIException {
		if (value == null) {
			ICDIType t = getType();
			if (t instanceof ICDIBoolType) {
				value = new BoolValue(this);
			} else if (t instanceof ICDICharType) {
				value = new CharValue(this);
			} else if (t instanceof ICDIWCharType) {
				value = new WCharValue(this);
			} else if (t instanceof ICDIShortType) {
				value = new ShortValue(this);
			} else if (t instanceof ICDIIntType) {
				value = new IntValue(this);
			} else if (t instanceof ICDILongType) {
				value = new LongValue(this);
			} else if (t instanceof ICDILongLongType) {
				value = new LongLongValue(this);
			} else if (t instanceof ICDIEnumType) {
				value = new EnumValue(this);
			} else if (t instanceof ICDIFloatType) {
				value = new FloatValue(this);
			} else if (t instanceof ICDIDoubleType) {
				value = new DoubleValue(this);
			} else if (t instanceof ICDIFunctionType) {
				value = new FunctionValue(this);
			} else if (t instanceof ICDIPointerType) {
				value = new PointerValue(this);
			} else if (t instanceof ICDIReferenceType) {
				value = new ReferenceValue(this);
			} else if (t instanceof ICDIArrayType) {
				value = new ArrayValue(this);
			} else if (t instanceof ICDIStructType) {
				value = new StructValue(this);
			} else {
				value = new Value(this);
			}
		}
		return value;
	}

	/**
	 * @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#setValue(ICDIValue)
	 */
	public void setValue(ICDIValue value) throws CDIException {
		setValue(value.getValueString());
	}

	/**
	 * @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#setValue(String)
	 */
	public void setValue(String expression) throws CDIException {
		Session session = (Session) (getTarget().getSession());
		MISession mi = session.getMISession();
		CommandFactory factory = mi.getCommandFactory();
		MIVarAssign var = factory.createMIVarAssign(miVar.getVarName(), expression);
		try {
			mi.postCommand(var);
			MIInfo info = var.getMIInfo();
			if (info == null) {
				throw new CDIException("No answer");
			}
		} catch (MIException e) {
			throw new MI2CDIException(e);
		}

		// If the assign was succesfull fire a MIVarChangedEvent() for the variable
		// Note GDB will not fire an event for the changed variable we have to do it manually.
		MIVarChangedEvent change = new MIVarChangedEvent(var.getToken(), miVar.getVarName());
		mi.fireEvent(change);

		// Changing values may have side effects i.e. affecting other variables
		// if the manager is on autoupdate check all the other variables.
		// Note: This maybe very costly.
		if (this instanceof Register) {
			// If register was on autoupdate, update all the other registers
			// assigning may have side effects i.e. affecting other registers.
			ICDIRegisterManager mgr = session.getRegisterManager();
			if (mgr.isAutoUpdate()) {
				mgr.update();
			}
		} else if (this instanceof Expression) {
			// If expression was on autoupdate, update all the other expression
			// assigning may have side effects i.e. affecting other expressions.
			ICDIExpressionManager mgr = session.getExpressionManager();
			if (mgr.isAutoUpdate()) {
				mgr.update();
			}
		} else {
			// FIXME: Should we always call the Variable Manager ?
			ICDIVariableManager mgr = session.getVariableManager();
			if (mgr.isAutoUpdate()) {
				mgr.update();
			}
		}
	}

	/**
	 * Overload the implementation of VariableObject and let gdb
	 * handle it.
	 * @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#isEditable()
	 */
	public boolean isEditable() throws CDIException {
		if (editable == null) {
			MISession mi = ((Session) (getTarget().getSession())).getMISession();
			CommandFactory factory = mi.getCommandFactory();
			MIVarShowAttributes var = factory.createMIVarShowAttributes(miVar.getVarName());
			try {
				mi.postCommand(var);
				MIVarShowAttributesInfo info = var.getMIVarShowAttributesInfo();
				if (info == null) {
					throw new CDIException("No answer");
				}
				editable = String.valueOf(info.isEditable());
			} catch (MIException e) {
				throw new MI2CDIException(e);
			}
		}
		return (editable == null) ? false : editable.equalsIgnoreCase("true");
	}

	/**
	 * @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#setFormat()
	 */
	public void setFormat(int format) throws CDIException {
		int fmt = Format.toMIFormat(format);
		MISession mi = ((Session) (getTarget().getSession())).getMISession();
		CommandFactory factory = mi.getCommandFactory();
		MIVarSetFormat var = factory.createMIVarSetFormat(miVar.getVarName(), fmt);
		try {
			mi.postCommand(var);
			MIInfo info = var.getMIInfo();
			if (info == null) {
				throw new CDIException("No answer");
			}
		} catch (MIException e) {
			throw new MI2CDIException(e);
		}
	}

	/**
	 * @see org.eclipse.cdt.debug.core.cdi.model.ICDIVariable#equals()
	 */
	public boolean equals(ICDIVariable var) {
		if (var instanceof Variable) {
			Variable variable = (Variable) var;
			return miVar.getVarName().equals(variable.getMIVar().getVarName());
		}
		return super.equals(var);
	}

}
