/*******************************************************************************
 * 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
 *     Jesper Steen Møller <jesper@selskabet.org> - Bug 430839
 *******************************************************************************/
package org.eclipse.jdt.internal.debug.core.model;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.debug.core.DebugException;
import org.eclipse.jdt.debug.core.IJavaClassType;
import org.eclipse.jdt.debug.core.IJavaInterfaceType;
import org.eclipse.jdt.debug.core.IJavaObject;
import org.eclipse.jdt.debug.core.IJavaThread;
import org.eclipse.jdt.debug.core.IJavaValue;

import com.sun.jdi.ClassType;
import com.sun.jdi.InterfaceType;
import com.sun.jdi.Method;
import com.sun.jdi.ObjectReference;
import com.sun.jdi.Value;

/**
 * The class of an object in a debug target.
 */
public class JDIClassType extends JDIReferenceType implements IJavaClassType {

	/**
	 * Constructs a new class type on the given target referencing the specified
	 * class type.
	 */
	public JDIClassType(JDIDebugTarget target, ClassType type) {
		super(target, type);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaClassType#newInstance(java.lang.String,
	 * org.eclipse.jdt.debug.core.IJavaValue[],
	 * org.eclipse.jdt.debug.core.IJavaThread)
	 */
	@Override
	public IJavaObject newInstance(String signature, IJavaValue[] args,
			IJavaThread thread) throws DebugException {
		if (getUnderlyingType() instanceof ClassType) {
			ClassType clazz = (ClassType) getUnderlyingType();
			JDIThread javaThread = (JDIThread) thread;
			List<Value> arguments = convertArguments(args);
			Method method = null;
			try {
				List<Method> methods = clazz.methodsByName("<init>", signature); //$NON-NLS-1$
				if (methods.isEmpty()) {
					requestFailed(
							MessageFormat.format(
									JDIDebugModelMessages.JDIClassType_Type_does_not_implement_cosntructor,
									signature), null);
				} else {
					method = methods.get(0);
				}
			} catch (RuntimeException e) {
				targetRequestFailed(
						MessageFormat.format(
								JDIDebugModelMessages.JDIClassType_exception_while_performing_method_lookup_for_constructor,
								e.toString(), signature), e);
			}
			ObjectReference result = javaThread.newInstance(clazz, method,
					arguments);
			return (IJavaObject) JDIValue.createValue(getJavaDebugTarget(),
					result);
		}
		requestFailed(
				JDIDebugModelMessages.JDIClassType_Type_is_not_a_class_type,
				null);
		// execution will not fall through to here,
		// as #requestFailed will throw an exception
		return null;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.eclipse.jdt.debug.core.IJavaClassType#sendMessage(java.lang.String,
	 * java.lang.String, org.eclipse.jdt.debug.core.IJavaValue[],
	 * org.eclipse.jdt.debug.core.IJavaThread)
	 */
	@Override
	public IJavaValue sendMessage(String selector, String signature,
			IJavaValue[] args, IJavaThread thread) throws DebugException {
		if (getUnderlyingType() instanceof ClassType) {
			ClassType clazz = (ClassType) getUnderlyingType();
			JDIThread javaThread = (JDIThread) thread;
			List<Value> arguments = convertArguments(args);
			Method method = null;
			try {
				List<Method> methods = clazz.methodsByName(selector, signature);
				if (methods.isEmpty()) {
					requestFailed(
							MessageFormat.format(
									JDIDebugModelMessages.JDIClassType_Type_does_not_implement_selector,
									selector, signature), null);
				} else {
					method = methods.get(0);
				}
			} catch (RuntimeException e) {
				targetRequestFailed(
						MessageFormat.format(
								JDIDebugModelMessages.JDIClassType_exception_while_performing_method_lookup_for_selector,
								e.toString(), selector, signature), e);
			}
			Value result = javaThread.invokeMethod(clazz, null, method,
					arguments, false);
			return JDIValue.createValue(getJavaDebugTarget(), result);
		}
		requestFailed(
				JDIDebugModelMessages.JDIClassType_Type_is_not_a_class_type,
				null);
		// execution will not fall through to here,
		// as #requestFailed will throw an exception
		return null;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaClassType#getSuperclass()
	 */
	@Override
	public IJavaClassType getSuperclass() throws DebugException {
		try {
			ClassType superclazz = ((ClassType) getUnderlyingType())
					.superclass();
			if (superclazz != null) {
				return (IJavaClassType) JDIType.createType(
						getJavaDebugTarget(), superclazz);
			}
		} catch (RuntimeException e) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIClassType_exception_while_retrieving_superclass,
							e.toString()), e);
		}
		// it is possible to return null
		return null;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaClassType#getAllInterfaces()
	 */
	@Override
	public IJavaInterfaceType[] getAllInterfaces() throws DebugException {
		try {
			List<InterfaceType> interfaceList = ((ClassType) getUnderlyingType())
					.allInterfaces();
			List<JDIType> javaInterfaceTypeList = new ArrayList<>(interfaceList.size());
			for(InterfaceType interfaceType : interfaceList) {
				if (interfaceType != null) {
					javaInterfaceTypeList.add(JDIType.createType(
							getJavaDebugTarget(), interfaceType));
				}
			}
			IJavaInterfaceType[] javaInterfaceTypeArray = new IJavaInterfaceType[javaInterfaceTypeList
					.size()];
			javaInterfaceTypeArray = javaInterfaceTypeList
					.toArray(javaInterfaceTypeArray);
			return javaInterfaceTypeArray;
		} catch (RuntimeException re) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIClassType_exception_while_retrieving_superclass,
							re.toString()), re);
		}
		return new IJavaInterfaceType[0];
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaClassType#getInterfaces()
	 */
	@Override
	public IJavaInterfaceType[] getInterfaces() throws DebugException {
		try {
			List<InterfaceType> interfaceList = ((ClassType) getUnderlyingType()).interfaces();
			List<JDIType> javaInterfaceTypeList = new ArrayList<>(interfaceList.size());
			for(InterfaceType interfaceType : interfaceList) {
				if (interfaceType != null) {
					javaInterfaceTypeList.add(JDIType.createType(
							getJavaDebugTarget(), interfaceType));
				}
			}
			IJavaInterfaceType[] javaInterfaceTypeArray = new IJavaInterfaceType[javaInterfaceTypeList
					.size()];
			javaInterfaceTypeArray = javaInterfaceTypeList
					.toArray(javaInterfaceTypeArray);
			return javaInterfaceTypeArray;
		} catch (RuntimeException re) {
			targetRequestFailed(
					MessageFormat.format(
							JDIDebugModelMessages.JDIClassType_exception_while_retrieving_superclass,
							re.toString()), re);
		}
		return new IJavaInterfaceType[0];
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.eclipse.jdt.debug.core.IJavaClassType#isEnum()
	 */
	@Override
	public boolean isEnum() {
		return ((ClassType) getReferenceType()).isEnum();
	}

}
