/*******************************************************************************
 * 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.jdi.internal;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.jdi.internal.jdwp.JdwpID;
import org.eclipse.jdi.internal.jdwp.JdwpObjectID;

import com.ibm.icu.text.MessageFormat;
import com.sun.jdi.ArrayType;
import com.sun.jdi.ClassNotLoadedException;
import com.sun.jdi.ClassType;
import com.sun.jdi.InterfaceType;
import com.sun.jdi.InternalException;
import com.sun.jdi.InvalidTypeException;
import com.sun.jdi.PrimitiveType;
import com.sun.jdi.ReferenceType;
import com.sun.jdi.Type;
import com.sun.jdi.Value;
import com.sun.jdi.VoidType;

/**
 * this class implements the corresponding interfaces declared by the JDI
 * specification. See the com.sun.jdi package for more information.
 *
 */
public abstract class ValueImpl extends MirrorImpl implements Value {
	/**
	 * Creates new ValueImpl.
	 */
	protected ValueImpl(String description, VirtualMachineImpl vmImpl) {
		super(description, vmImpl);
	}

	/**
	 * @returns type of value.
	 */
	@Override
	public abstract Type type();

	/**
	 * @returns type of value.
	 */
	public abstract byte getTag();

	/**
	 * @return Reads JDWP representation and returns new instance.
	 */
	public static ValueImpl readWithTag(MirrorImpl target, DataInputStream in)
			throws IOException {
		byte tag = target.readByte("object tag", JdwpID.tagMap(), in); //$NON-NLS-1$
		return readWithoutTag(target, tag, in);
	}

	/**
	 * @return Reads JDWP representation and returns new instance.
	 */
	public static ValueImpl readWithoutTag(MirrorImpl target, int type,
			DataInputStream in) throws IOException {
		VirtualMachineImpl vmImpl = target.virtualMachineImpl();
		// See also ArrayReference Impl.
		switch (type) {
		case ArrayReferenceImpl.tag:
			return ArrayReferenceImpl.read(target, in);
		case ClassLoaderReferenceImpl.tag:
			return ClassLoaderReferenceImpl.read(target, in);
		case ClassObjectReferenceImpl.tag:
			return ClassObjectReferenceImpl.read(target, in);
		case StringReferenceImpl.tag:
			return StringReferenceImpl.read(target, in);
		case ObjectReferenceImpl.tag:
			return ObjectReferenceImpl.readObjectRefWithoutTag(target, in);
		case ThreadGroupReferenceImpl.tag:
			return ThreadGroupReferenceImpl.read(target, in);
		case ThreadReferenceImpl.tag:
			return ThreadReferenceImpl.read(target, in);
		case BooleanValueImpl.tag:
			return BooleanValueImpl.read(target, in);
		case ByteValueImpl.tag:
			return ByteValueImpl.read(target, in);
		case CharValueImpl.tag:
			return CharValueImpl.read(target, in);
		case DoubleValueImpl.tag:
			return DoubleValueImpl.read(target, in);
		case FloatValueImpl.tag:
			return FloatValueImpl.read(target, in);
		case IntegerValueImpl.tag:
			return IntegerValueImpl.read(target, in);
		case LongValueImpl.tag:
			return LongValueImpl.read(target, in);
		case ShortValueImpl.tag:
			return ShortValueImpl.read(target, in);
		case VoidValueImpl.tag:
			return new VoidValueImpl(vmImpl);
		case 0:
			return null;
		default:
			throw new InternalException(
					JDIMessages.ValueImpl_Invalid_Value_tag_encountered___1
							+ type);
		}
	}

	/**
	 * Writes value with value tag.
	 */
	public void writeWithTag(MirrorImpl target, DataOutputStream out)
			throws IOException {
		target.writeByte(getTag(), "tag", JdwpID.tagMap(), out); //$NON-NLS-1$
		write(target, out);
	}

	/**
	 * Writes value without value tag.
	 */
	public abstract void write(MirrorImpl target, DataOutputStream out)
			throws IOException;

	/**
	 * Writes null value without value tag.
	 */
	public static void writeNull(MirrorImpl target, DataOutputStream out)
			throws IOException {
		JdwpObjectID nullID = new JdwpObjectID(target.virtualMachineImpl());
		nullID.write(out);
		if (target.fVerboseWriter != null)
			target.fVerboseWriter.println("objectReference", nullID.value()); //$NON-NLS-1$
	}

	/**
	 * Writes null value with value tag.
	 */
	public static void writeNullWithTag(MirrorImpl target, DataOutputStream out)
			throws IOException {
		target.writeByte(ObjectReferenceImpl.tag, "tag", JdwpID.tagMap(), out); //$NON-NLS-1$
		writeNull(target, out);
	}

	/**
	 * Check the type and the vm of each values, according to the associated
	 * type. For primitive values, convert the value for match the given type if
	 * needed. The two list must have the same size.
	 *
	 * @return the (converted) values.
	 * @see checkValue(Value, Type, VirtualMachineImpl)
	 */
	protected static List<Value> checkValues(List<?extends Value> values, List<Type> types,
			VirtualMachineImpl vm) throws InvalidTypeException {
		List<Value> result = new ArrayList<Value>(values.size());
		Iterator<? extends Value> iterValues = values.iterator();
		Iterator<Type> iterTypes = types.iterator();
		while (iterValues.hasNext()) {
			Value value = iterValues.next();
			Type type = iterTypes.next();
			result.add(checkValue(value, type, vm));
		}
		return result;
	}

	/**
	 * Check the type and the vm of the given value. In case of primitive value,
	 * the value is converted if needed.
	 *
	 * @return the (converted) value.
	 * @throws InvalidTypeException
	 *             if the given value is no assignment compatible with the given
	 *             type.
	 * @see checkPrimitiveValue(PrimitiveValueImpl, PrimitiveTypeImpl,
	 *      PrimitiveTypeImpl)
	 */
	public static ValueImpl checkValue(Value value, Type type,
			VirtualMachineImpl vm) throws InvalidTypeException {
		if (value == null) {
			if (!(type instanceof PrimitiveType)) {
				return null;
			}
		} else {
			vm.checkVM(value);
			TypeImpl valueType = (TypeImpl) value.type();
			if (valueType instanceof PrimitiveType
					&& type instanceof PrimitiveType) {
				return checkPrimitiveValue((PrimitiveValueImpl) value,
						(PrimitiveTypeImpl) valueType, (PrimitiveTypeImpl) type);
			}
			if (valueType instanceof ReferenceType
					&& type instanceof ReferenceType) {
				checkReferenceType((ReferenceType) valueType,
						(ReferenceType) type);
				return (ValueImpl) value;
			}
			if (valueType instanceof VoidType && type instanceof VoidType) {
				return (VoidValueImpl) value;
			}
		}
		throw new InvalidTypeException(
				MessageFormat
						.format(JDIMessages.ValueImpl_Type_of_the_value_not_compatible_with_the_expected_type__1,
								new Object[] {
										value != null ? value.type().name()
												: "null", type.name() })); //$NON-NLS-1$
	}

	/**
     */
	private static void checkReferenceType(ReferenceType valueType,
			ReferenceType type) throws InvalidTypeException {
		if (valueType instanceof ArrayType) {
			if (type instanceof ArrayType) {
				try {
					Type valueComponentType = ((ArrayType) valueType)
							.componentType();
					Type componentType = ((ArrayType) type).componentType();
					if (valueComponentType instanceof PrimitiveType) {
						if (valueComponentType.equals(componentType)) {
							return;
						}
					} else if (valueComponentType instanceof ReferenceType
							&& componentType instanceof ReferenceType) {
						checkReferenceType((ReferenceType) valueComponentType,
								(ReferenceType) componentType);
						return;
					}
				} catch (ClassNotLoadedException e) {
					// should not append
				}
			} else {
				// an array can be assigned to an object
				if (type.signature().equals("Ljava/lang/Object;")) { //$NON-NLS-1$
					return;
				}
			}
		} else {
			if (type instanceof ClassType) {
				if (valueType instanceof ClassType) {
					ClassType superClass = (ClassType) valueType;
					while (superClass != null) {
						if (superClass.equals(type)) {
							return;
						}
						superClass = superClass.superclass();
					}
				} else if (valueType instanceof InterfaceType) {
					// an interface can be assigned to an object
					if (type.signature().equals("Ljava/lang/Object;")) { //$NON-NLS-1$
						return;
					}
				}
			} else if (type instanceof InterfaceType) {
				if (valueType instanceof InterfaceType) {
					if (checkInterfaceType((InterfaceType) valueType,
							(InterfaceType) type)) {
						return;
					}
				} else {
					List<InterfaceType> interfaces = ((ClassType) valueType).allInterfaces();
					for (Iterator<InterfaceType> iter = interfaces.iterator(); iter.hasNext();) {
						if (checkInterfaceType(iter.next(),
								(InterfaceType) type)) {
							return;
						}
					}
				}
			}
		}

		throw new InvalidTypeException(
				MessageFormat
						.format(JDIMessages.ValueImpl_Type_of_the_value_not_compatible_with_the_expected_type__1,
								new Object[] { valueType.name(), type.name() }));
	}

	private static boolean checkInterfaceType(InterfaceType valueType,
			InterfaceType type) {
		if (valueType.equals(type)) {
			return true;
		}
		List<InterfaceType> superInterfaces = valueType.superinterfaces();
		for (Iterator<InterfaceType> iter = superInterfaces.iterator(); iter.hasNext();) {
			if (checkInterfaceType(iter.next(), type)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Check the type of the given value, and convert the value to the given
	 * type if needed (see Java Language Spec, section 5.2).
	 *
	 * @return the (converted) value.
	 * @throws InvalidTypeException
	 *             if the given value is no assignment compatible with the given
	 *             type.
	 */
	protected static ValueImpl checkPrimitiveValue(PrimitiveValueImpl value,
			PrimitiveTypeImpl valueType, PrimitiveTypeImpl type)
			throws InvalidTypeException {
		char valueTypeSignature = valueType.signature().charAt(0);
		char typeSignature = type.signature().charAt(0);
		if (valueTypeSignature == typeSignature) {
			return value;
		}
		VirtualMachineImpl vm = value.virtualMachineImpl();
		switch (typeSignature) {
		case 'D':
			if (valueTypeSignature != 'Z') {
				return new DoubleValueImpl(vm, new Double(value.doubleValue()));
			}
			break;
		case 'F':
			if (valueTypeSignature != 'Z' && valueTypeSignature != 'D') {
				return new FloatValueImpl(vm, new Float(value.floatValue()));
			}
			break;
		case 'J':
			if (valueTypeSignature != 'Z' && valueTypeSignature != 'D'
					&& valueTypeSignature != 'F') {
				return new LongValueImpl(vm, new Long(value.longValue()));
			}
			break;
		case 'I':
			if (valueTypeSignature == 'B' || valueTypeSignature == 'C'
					|| valueTypeSignature == 'S') {
				return new IntegerValueImpl(vm, new Integer(value.intValue()));
			}
			break;
		case 'S':
			if (valueTypeSignature == 'B') {
				return new ShortValueImpl(vm, new Short(value.shortValue()));
			}
			break;
		}
		throw new InvalidTypeException(
				MessageFormat
						.format(JDIMessages.ValueImpl_Type_of_the_value_not_compatible_with_the_expected_type__1,
								new Object[] { valueType.name(), type.name() }));
	}
}
