/*******************************************************************************
 * Copyright (c) 2000, 2012 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.core.model;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.jdt.debug.core.IJavaValue;
import org.eclipse.jdt.debug.core.IJavaVariable;

import com.ibm.icu.text.MessageFormat;
import com.sun.jdi.ArrayReference;
import com.sun.jdi.ArrayType;
import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.InvalidTypeException;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.Type;
import com.sun.jdi.Value;

/**
 * An entry in an array.
 */

public class JDIArrayEntryVariable extends JDIModificationVariable {

	/**
	 * The index of the variable entry
	 */
	private int fIndex;

	/**
	 * The array object
	 */
	private ArrayReference fArray;

	/**
	 * The reference type name of this variable. Cached lazily.
	 */
	private String fReferenceTypeName = null;

	/**
	 * When created for a logical structure we hold onto the original
	 * non-logical object for purposes of equality. This way a logical
	 * structure's children remain more stable in the variables view.
	 *
	 * This is <code>null</code> when not created for a logical structure.
	 */
	private IJavaValue fLogicalParent;

	/**
	 * Constructs an array entry at the given index in an array.
	 *
	 * @param target
	 *            debug target containing the array entry
	 * @param array
	 *            array containing the entry
	 * @param index
	 *            index into the array
	 * @param logicalParent
	 *            original logical parent value, or <code>null</code> if not a
	 *            child of a logical structure
	 */
	public JDIArrayEntryVariable(JDIDebugTarget target, ArrayReference array,
			int index, IJavaValue logicalParent) {
		super(target);
		fArray = array;
		fIndex = index;
		fLogicalParent = logicalParent;
	}

	/**
	 * Returns this variable's current underlying value.
	 */
	@Override
	protected Value retrieveValue() {
		ArrayReference ar = getArrayReference();
		if (ar != null) {
			return ar.getValue(getIndex());
		}
		return null;
	}

	/**
	 * @see IVariable#getName()
	 */
	@Override
	public String getName() {
		return "[" + getIndex() + "]"; //$NON-NLS-2$ //$NON-NLS-1$
	}

	@Override
	protected void setJDIValue(Value value) throws DebugException {
		ArrayReference ar = getArrayReference();
		if (ar == null) {
			requestFailed(
					JDIDebugModelMessages.JDIArrayEntryVariable_value_modification_failed,
					null);
		}
		try {
			ar.setValue(getIndex(), value);
			fireChangeEvent(DebugEvent.CONTENT);
		} catch (ClassNotLoadedException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIArrayEntryVariable_exception_modifying_variable_value,
							e.toString()), e);
		} catch (InvalidTypeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIArrayEntryVariable_exception_modifying_variable_value,
							e.toString()), e);
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIArrayEntryVariable_exception_modifying_variable_value,
							e.toString()), e);
		}

	}

	protected ArrayReference getArrayReference() {
		return fArray;
	}

	protected int getIndex() {
		return fIndex;
	}

	/**
	 * @see IVariable#getReferenceTypeName()
	 */
	@Override
	public String getReferenceTypeName() throws DebugException {
		try {
			if (fReferenceTypeName == null) {
				fReferenceTypeName = stripBrackets(JDIReferenceType
						.getGenericName(getArrayReference().referenceType()));
			}
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIArrayEntryVariable_exception_retrieving_reference_type,
							e.toString()), e);
			// execution will not reach this line, as
			// #targetRequestFailed will thrown an exception
			return null;
		}
		return fReferenceTypeName;
	}

	/**
	 * Given a type name, strip out one set of array brackets and return the
	 * result. Example: "int[][][]" becomes "int[][]".
	 */
	protected String stripBrackets(String typeName) {
		int lastLeft = typeName.lastIndexOf("[]"); //$NON-NLS-1$
		if (lastLeft < 0) {
			return typeName;
		}
		StringBuffer buffer = new StringBuffer(typeName);
		buffer.replace(lastLeft, lastLeft + 2, ""); //$NON-NLS-1$
		return buffer.toString();
	}

	/**
	 * @see IJavaVariable#getSignature()
	 */
	@Override
	public String getSignature() throws DebugException {
		try {
			return ((ArrayType) getArrayReference().type())
					.componentSignature();
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIArrayEntryVariable_exception_retrieving_type_signature,
							e.toString()), e);
			// execution will not reach this line, as
			// #targetRequestFailed will thrown an exception
			return null;
		}
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaVariable#getGenericSignature()
	 */
	@Override
	public String getGenericSignature() throws DebugException {
		try {
			ReferenceType referenceType = getArrayReference().referenceType();
			String genericSignature = referenceType.genericSignature();
			if (genericSignature != null) {
				return genericSignature;
			}
			return referenceType.signature();
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIArrayEntryVariable_exception_retrieving_type_signature,
							e.toString()), e);
			// execution will not reach this line, as
			// #targetRequestFailed will thrown an exception
			return null;
		}
	}

	/**
	 * @see JDIVariable#getUnderlyingType()
	 */
	@Override
	protected Type getUnderlyingType() throws DebugException {
		try {
			return ((ArrayType) getArrayReference().type()).componentType();
		} catch (ClassNotLoadedException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIArrayEntryVariable_exception_while_retrieving_type_of_array_entry,
							e.toString()), e);
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIArrayEntryVariable_exception_while_retrieving_type_of_array_entry,
							e.toString()), e);
		}
		// this line will not be executed as an exception
		// will be throw in type retrieval fails
		return null;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj instanceof JDIArrayEntryVariable) {
			JDIArrayEntryVariable entry = (JDIArrayEntryVariable) obj;
			if (fLogicalParent != null) {
				try {
					return fLogicalParent.equals(entry.fLogicalParent)
							&& getValue().equals(entry.getValue());
				} catch (CoreException e) {
				}
			}
			return entry.getArrayReference().equals(getArrayReference())
					&& entry.getIndex() == getIndex();
		}
		return false;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		if (fLogicalParent != null) {
			return fLogicalParent.hashCode() + getIndex();
		}
		return getArrayReference().hashCode() + getIndex();
	}

}
