/*******************************************************************************
 * 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() }));
	}
}
