/*******************************************************************************
 * Copyright (c) 2000, 2015 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.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() }));
	}
}
