/*******************************************************************************
 * Copyright (c) 2000, 2011 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.core.model;

import java.text.MessageFormat;

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.IJavaFieldVariable;
import org.eclipse.jdt.debug.core.IJavaModifiers;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaReferenceType;
import org.eclipse.jdt.debug.core.IJavaType;
import org.eclipse.jdt.debug.core.IJavaValue;
import org.eclipse.jdt.debug.core.IJavaVariable;

import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.ClassType;
import com.sun.jdi.Field;
import com.sun.jdi.InterfaceType;
import com.sun.jdi.InvalidTypeException;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.Type;
import com.sun.jdi.Value;

/**
 * A field member.
 */
public class JDIFieldVariable extends JDIModificationVariable implements
		IJavaFieldVariable {
	/**
	 * The underlying field
	 */
	private Field fField;
	/**
	 * The object containing the field, or <code>null</code> for a static field.
	 */
	private ObjectReference fObject;
	/**
	 * The type containing the field.
	 */
	private ReferenceType fType;

	/**
	 * 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.
	 */
	private IJavaValue fLogicalParent;

	/**
	 * Constructs a field for the given field.
	 */
	public JDIFieldVariable(JDIDebugTarget target, Field field,
			ObjectReference objectRef, IJavaValue logicalParent) {
		super(target);
		fField = field;
		if (!field.isStatic()) {
			fObject = objectRef;
		}
		fType = (ReferenceType) objectRef.type();
		fLogicalParent = logicalParent;
	}

	/**
	 * Constructs a field to wrap the given field.
	 */
	public JDIFieldVariable(JDIDebugTarget target, Field field,
			ReferenceType refType) {
		super(target);
		fField = field;
		fType = refType;
	}

	/**
	 * Returns this variable's current <code>Value</code>.
	 */
	@Override
	protected Value retrieveValue() {
		if (getField().isStatic()) {
			return (getField().declaringType().getValue(getField()));
		}
		return getObjectReference().getValue(getField());
	}

	/**
	 * @see IJavaFieldVariable#getDeclaringType()
	 */
	@Override
	public IJavaType getDeclaringType() {
		return JDIType.createType((JDIDebugTarget) getDebugTarget(),
				fField.declaringType());
	}

	/**
	 * @see IVariable#getName()
	 */
	@Override
	public String getName() throws DebugException {
		try {
			return getField().name();
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIFieldVariable_exception_retrieving_field_name,
							e.toString()), e);
			// execution will not reach this line, as
			// #targetRequestFailed will thrown an exception
			return null;
		}
	}

	@Override
	protected void setJDIValue(Value value) throws DebugException {
		try {
			if (isStatic()) {
				ReferenceType declaringType = getField().declaringType();
				if (declaringType instanceof InterfaceType) {
					requestFailed(JDIDebugModelMessages.JDIFieldVariable_0,
							null);
				}
				((ClassType) declaringType).setValue(getField(), value);
			} else {
				getObjectReference().setValue(getField(), value);
			}
			fireChangeEvent(DebugEvent.CONTENT);
		} catch (ClassNotLoadedException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIFieldVariable_exception_modifying_value,
							e.toString()), e);
		} catch (InvalidTypeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIFieldVariable_exception_modifying_value,
							e.toString()), e);
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIFieldVariable_exception_modifying_value,
							e.toString()), e);
		}

	}

	/**
	 * @see IJavaVariable#isVolatile()
	 */
	@Override
	public boolean isVolatile() {
		return getField().isVolatile();
	}

	/**
	 * @see IJavaVariable#isTransient()
	 */
	@Override
	public boolean isTransient() {
		return getField().isTransient();
	}

	/**
	 * @see IJavaModifiers#isSynthetic()
	 */
	@Override
	public boolean isSynthetic() {
		return getField().isSynthetic();
	}

	/**
	 * @see IJavaModifiers#isPublic()
	 */
	@Override
	public boolean isPublic() {
		return getField().isPublic();
	}

	/**
	 * @see IJavaModifiers#isPrivate()
	 */
	@Override
	public boolean isPrivate() {
		return getField().isPrivate();
	}

	/**
	 * @see IJavaModifiers#isProtected()
	 */
	@Override
	public boolean isProtected() {
		return getField().isProtected();
	}

	/**
	 * @see IJavaModifiers#isPackagePrivate()
	 */
	@Override
	public boolean isPackagePrivate() {
		return getField().isPackagePrivate();
	}

	/**
	 * @see IJavaModifiers#isStatic()
	 */
	@Override
	public boolean isStatic() {
		return getField().isStatic();
	}

	/**
	 * @see IJavaModifiers#isFinal()
	 */
	@Override
	public boolean isFinal() {
		return getField().isFinal();
	}

	/**
	 * @see IVariable#getReferenceTypeName()
	 */
	@Override
	public String getReferenceTypeName() throws DebugException {
		String genericSignature = getField().genericSignature();
		if (genericSignature != null) {
			return JDIReferenceType.getTypeName(genericSignature);
		}
		Type underlyingType = getUnderlyingType();
		if (underlyingType instanceof ReferenceType) {
			return JDIReferenceType
					.getGenericName((ReferenceType) underlyingType);
		}
		return getField().typeName();
	}

	/**
	 * @see IJavaVariable#getSignature()
	 */
	@Override
	public String getSignature() throws DebugException {
		try {
			return getField().signature();
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIFieldVariable_exception_retrieving_field_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 {
			String genericSignature = fField.genericSignature();
			if (genericSignature != null) {
				return genericSignature;
			}
			return fField.signature();
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIFieldVariable_exception_retrieving_field_signature,
							e.toString()), e);
			// execution will not reach this line, as
			// #targetRequestFailed will thrown an exception
			return null;
		}
	}

	public Field getField() {
		return fField;
	}

	public ObjectReference getObjectReference() {
		return fObject;
	}

	public ReferenceType getReferenceType() {
		return fType;
	}

	@Override
	public boolean supportsValueModification() {
		if (getField().declaringType() instanceof InterfaceType) {
			return false;
		}
		return super.supportsValueModification();
	}

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

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

	/**
	 * @see java.lang.Object#equals(Object)
	 */
	@Override
	public boolean equals(Object o) {
		if (o instanceof JDIFieldVariable) {
			JDIFieldVariable f = (JDIFieldVariable) o;
			if (fLogicalParent != null) {
				return fLogicalParent.equals(f.fLogicalParent)
						&& f.fField.equals(fField);
			}
			if (fObject != null) {
				return fObject.equals(f.fObject) && f.fField.equals(fField);
			}
			return f.fField.equals(fField);
		}
		return false;
	}

	/**
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		if (fLogicalParent != null) {
			return fLogicalParent.hashCode() + fField.hashCode();
		}
		if (fObject != null) {
			return fField.hashCode() + fObject.hashCode();
		}
		return fField.hashCode();
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaFieldVariable#getObject()
	 */
	@Override
	public IJavaObject getReceiver() {
		ObjectReference objectReference = getObjectReference();
		if (objectReference == null) {
			return null;
		}
		return (IJavaObject) JDIValue.createValue(getJavaDebugTarget(),
				objectReference);
	}

	@Override
	public IJavaReferenceType getReceivingType() {
		return (IJavaReferenceType) JDIType.createType(getJavaDebugTarget(),
				getReferenceType());
	}

}
