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