/*******************************************************************************
 * Copyright (c) 2000, 2015 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 java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IValue;
import org.eclipse.debug.core.model.IVariable;

import org.eclipse.jdt.debug.core.IJavaType;
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.ClassObjectReference;
import com.sun.jdi.Field;
import com.sun.jdi.ObjectCollectedException;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.PrimitiveValue;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.StringReference;
import com.sun.jdi.Type;
import com.sun.jdi.VMDisconnectedException;
import com.sun.jdi.Value;

/**
 * Represents the value of a java variable
 *
 * @see IJavaValue
 */
public class JDIValue extends JDIDebugElement implements IJavaValue {

	private Value fValue;
	private List<IJavaVariable> fVariables;

	/**
	 * A flag indicating if this value is still allocated (valid)
	 */
	private boolean fAllocated = true;

	/**
	 * When created for a logical structure we hold onto the original
	 * non-logical value 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.
	 */
	protected IJavaValue fLogicalParent;

	/**
	 * Constructor
	 *
	 * @param target
	 *            debug target that this value belongs to
	 * @param value
	 *            the underlying value this value represents
	 */
	public JDIValue(JDIDebugTarget target, Value value) {
		super(target);
		fValue = value;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.internal.debug.core.model.JDIDebugElement#getAdapter(
	 * java.lang.Class)
	 */
	@SuppressWarnings("unchecked")
	@Override
	public <T> T getAdapter(Class<T> adapter) {
		if (adapter == IJavaValue.class) {
			return (T) this;
		}
		return super.getAdapter(adapter);
	}

	/**
	 * Creates the appropriate kind of value - i.e. a primitive value, object,
	 * class object, array, or <code>null</code>.
	 */
	public static JDIValue createValue(JDIDebugTarget target, Value value) {
		if (value == null) {
			return new JDINullValue(target);
		}
		if (value instanceof ArrayReference) {
			return new JDIArrayValue(target, (ArrayReference) value);
		}
		if (value instanceof ClassObjectReference) {
			return new JDIClassObjectValue(target, (ClassObjectReference) value);
		}
		if (value instanceof ObjectReference) {
			return new JDIObjectValue(target, (ObjectReference) value);
		}
		if (value instanceof PrimitiveValue) {
			return new JDIPrimitiveValue(target, value);
		}
		return new JDIValue(target, value);
	}

	/**
	 * @see IValue#getValueString()
	 */
	@Override
	public String getValueString() throws DebugException {
		if (fValue == null) {
			return JDIDebugModelMessages.JDIValue_null_4;
		}
		if (fValue instanceof StringReference) {
			try {
				return ((StringReference) fValue).value();
			} catch (ObjectCollectedException e) {
				return JDIDebugModelMessages.JDIValue_deallocated;
			} catch (RuntimeException e) {
				targetRequestFailed(
						MessageFormat.format(
								JDIDebugModelMessages.JDIValue_exception_retrieving_value,
								new Object[] { e.toString() }), e);
				// execution will not reach this line, as
				// #targetRequestFailed will thrown an exception
				return null;
			}
		}
		if (fValue instanceof ObjectReference) {
			StringBuffer name = new StringBuffer();
			if (fValue instanceof ClassObjectReference) {
				name.append('(');
				name.append(((ClassObjectReference) fValue).reflectedType());
				name.append(')');
			}
			long id = 0;
			try {
				id = ((ObjectReference) fValue).uniqueID();
			} catch (RuntimeException e) {
				targetRequestFailed(
						MessageFormat.format(
								JDIDebugModelMessages.JDIValue_exception_retrieving_unique_id,
								new Object[] { e.toString() }), e);
				// execution will not reach this line, as
				// #targetRequestFailed will thrown an exception
				return null;
			}
			name.append(" "); //$NON-NLS-1$
			name.append(MessageFormat.format(
					JDIDebugModelMessages.JDIValue_id_8,
					new Object[] { String.valueOf(id) }));
			return name.toString();
		}
		// see bug 43285
		return String.valueOf(fValue);
	}

	/**
	 * @see IValue#getReferenceTypeName()
	 */
	@Override
	public String getReferenceTypeName() throws DebugException {
		try {
			if (fValue == null) {
				return JDIDebugModelMessages.JDIValue_null_4;
			}
			return getUnderlyingType().name();
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIValue_exception_retrieving_reference_type_name,
							new Object[] { e.toString() }), e);
			// execution will not reach this line, as
			// #targetRequestFailed will thrown an exception
			return null;
		}
	}

	/**
	 * @see Object#hashCode()
	 */
	@Override
	public int hashCode() {
		if (fValue == null) {
			return getClass().hashCode();
		}
		return fValue.hashCode();
	}

	/**
	 * @see Object#equals(Object)
	 */
	@Override
	public boolean equals(Object o) {
		if (this == o) {
			return true;
		}
		if (o instanceof JDIValue) {
			Value other = ((JDIValue) o).getUnderlyingValue();
			if (fValue == null) {
				return false;
			}
			if (other == null) {
				return false;
			}
			return fValue.equals(other);
		}
		return false;
	}

	/**
	 * @see IValue#getVariables()
	 */
	@Override
	public IVariable[] getVariables() throws DebugException {
		List<IJavaVariable> list = getVariablesList();
		return list.toArray(new IVariable[list.size()]);
	}

	/**
	 * Returns a list of variables that are children of this value. The result
	 * is cached.
	 *
	 * @return list of variable children
	 * @throws DebugException
	 */
	protected synchronized List<IJavaVariable> getVariablesList() throws DebugException {
		if (fVariables != null) {
			return fVariables;
		} else if (fValue instanceof ObjectReference) {
			ObjectReference object = (ObjectReference) fValue;
			fVariables = new ArrayList<>();
			if (isArray()) {
				try {
					int length = getArrayLength();
					for (int i = 0; i < length; i++) {
						fVariables.add(new JDIArrayEntryVariable(
								getJavaDebugTarget(), getArrayReference(), i,
								fLogicalParent));
					}
				} catch (DebugException e) {
					if (e.getCause() instanceof ObjectCollectedException) {
						return Collections.EMPTY_LIST;
					}
					throw e;
				}
			} else {
				List<Field> fields = null;
				try {
					ReferenceType refType = object.referenceType();
					fields = refType.allFields();
				} catch (ObjectCollectedException e) {
					return Collections.EMPTY_LIST;
				} catch (RuntimeException e) {
					targetRequestFailed(
							MessageFormat.format(
									JDIDebugModelMessages.JDIValue_exception_retrieving_fields,
									new Object[] { e.toString() }), e);
					// execution will not reach this line, as
					// #targetRequestFailed will thrown an exception
					return null;
				}
				Iterator<Field> list = fields.iterator();
				while (list.hasNext()) {
					Field field = list.next();
					fVariables.add(new JDIFieldVariable(
							(JDIDebugTarget) getDebugTarget(), field, object,
							fLogicalParent));
				}
				Collections.sort(fVariables, new Comparator<IJavaVariable>() {
					@Override
					public int compare(IJavaVariable a, IJavaVariable b) {
						return sortChildren(a, b);
					}
				});
			}

			return fVariables;
		} else {
			return Collections.EMPTY_LIST;
		}
	}

	/**
	 * Group statics and instance variables, sort alphabetically within each
	 * group.
	 */
	protected int sortChildren(Object a, Object b) {
		IJavaVariable v1 = (IJavaVariable) a;
		IJavaVariable v2 = (IJavaVariable) b;

		try {
			boolean v1isStatic = v1.isStatic();
			boolean v2isStatic = v2.isStatic();
			if (v1isStatic && !v2isStatic) {
				return -1;
			}
			if (!v1isStatic && v2isStatic) {
				return 1;
			}
			return v1.getName().compareToIgnoreCase(v2.getName());
		} catch (DebugException de) {
			logError(de);
			return -1;
		}
	}

	/**
	 * Returns whether this value is an array
	 */
	protected boolean isArray() {
		return fValue instanceof ArrayReference;
	}

	/**
	 * Returns this value as an array reference, or <code>null</code>
	 */
	protected ArrayReference getArrayReference() {
		if (isArray()) {
			return (ArrayReference) fValue;
		}
		return null;
	}

	/**
	 * @see IValue#isAllocated()
	 */
	@Override
	public boolean isAllocated() throws DebugException {
		if (fAllocated) {
			if (fValue instanceof ObjectReference) {
				try {
					fAllocated = !((ObjectReference) fValue).isCollected();
				} catch (VMDisconnectedException e) {
					// if the VM disconnects, this value is not allocated
					fAllocated = false;
				} catch (RuntimeException e) {
					targetRequestFailed(
							MessageFormat.format(
									JDIDebugModelMessages.JDIValue_exception_is_collected,
									new Object[] { e.toString() }), e);
					// execution will fall through, as
					// #targetRequestFailed will thrown an exception
				}
			} else {
				JDIDebugTarget dt = (JDIDebugTarget) getDebugTarget();
				fAllocated = dt.isAvailable();
			}
		}
		return fAllocated;
	}

	/**
	 * @see IJavaValue#getSignature()
	 */
	@Override
	public String getSignature() throws DebugException {
		try {
			if (fValue != null) {
				return fValue.type().signature();
			}
			return null;
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIValue_exception_retrieving_type_signature,
							new Object[] { 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.IJavaValue#getGenericSignature()
	 */
	@Override
	public String getGenericSignature() throws DebugException {
		try {
			if (fValue != null) {
				Type type = fValue.type();
				if (type instanceof ReferenceType) {
					return ((ReferenceType) type).genericSignature();
				}
				return null;
			}
			return null;
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIValue_exception_retrieving_type_signature,
							new Object[] { e.toString() }), e);
			// execution will not reach this line, as
			// #targetRequestFailed will thrown an exception
			return null;
		}
	}

	/**
	 * @see IJavaValue#getArrayLength()
	 */
	public int getArrayLength() throws DebugException {
		if (isArray()) {
			try {
				return getArrayReference().length();
			} catch (RuntimeException e) {
				targetRequestFailed(
						MessageFormat.format(
								JDIDebugModelMessages.JDIValue_exception_retrieving_length_of_array,
								new Object[] { e.toString() }), e);
			}
		}
		return -1;
	}

	/**
	 * Returns this value's underlying JDI value
	 */
	protected Value getUnderlyingValue() {
		return fValue;
	}

	/**
	 * @see IJavaValue#getJavaType()
	 */
	@Override
	public IJavaType getJavaType() throws DebugException {
		return JDIType.createType((JDIDebugTarget) getDebugTarget(),
				getUnderlyingType());
	}

	/**
	 * Returns this value's underlying type.
	 *
	 * @return type
	 * @exception DebugException
	 *                if this method fails. Reasons include:
	 *                <ul>
	 *                <li>Failure communicating with the VM. The
	 *                DebugException's status code contains the underlying
	 *                exception responsible for the failure.</li>
	 */
	protected Type getUnderlyingType() throws DebugException {
		try {
			return getUnderlyingValue().type();
		} catch (RuntimeException e) {
			targetRequestFailed(MessageFormat.format(
					JDIDebugModelMessages.JDIValue_exception_retrieving_type,
					new Object[] { e.toString() }), e);
			// execution will not fall through to here,
			// as #requestFailed will throw an exception
			return null;
		}
	}

	/**
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return getUnderlyingValue().toString();
	}

	/**
	 * @see IValue#hasVariables()
	 */
	@Override
	public boolean hasVariables() throws DebugException {
		return getVariablesList().size() > 0;
	}

	/**
	 * Sets the value that is the original non-logical value that this child
	 * value was computed for.
	 *
	 * @param logicalParent
	 *            parent value
	 */
	public void setLogicalParent(IJavaValue logicalParent) {
		fLogicalParent = logicalParent;
	}

	/**
	 * Returns the value that is the original non-logical value that this child
	 * value was computed for or <code>null</code> if none
	 *
	 * @param logicalParent
	 *            parent value or <code>null</code>
	 */
	public IJavaValue getLogicalParent() {
		return fLogicalParent;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaValue#isNull()
	 */
	@Override
	public boolean isNull() {
		return false;
	}

}
