/*******************************************************************************
 * Copyright (c) 2001, 2005 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.jem.internal.proxy.common;
import java.lang.reflect.*;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * This is a class to do message/constructor work. 
 * Specifically to find the most appropriate method.
 */
public class MethodHelper {
	
	/*
	 * The class that is used to represent Null class type.
	 * 
	 * @since 1.0.0
	 */
	private static class NULL_CLASS {
	}
	
	public static final Class NULL_TYPE = NULL_CLASS.class;
	
	static final ArrayList sPrimitivesOrder;
	static final int sCharPos;
	
	static {
		sPrimitivesOrder = new ArrayList(6);
		sPrimitivesOrder.add(Byte.TYPE);
		sPrimitivesOrder.add(Short.TYPE);
		sPrimitivesOrder.add(Integer.TYPE);
		sPrimitivesOrder.add(Long.TYPE);
		sPrimitivesOrder.add(Float.TYPE);
		sPrimitivesOrder.add(Double.TYPE);

		// char can be treated like a short for purposes of ordering.
		sCharPos = sPrimitivesOrder.indexOf(Short.TYPE);
	}
	
	/**
	 * Return whether the type2 can be assigned to type1 in
	 * method argument conversion.
	 */
	public static boolean isAssignableFrom(Class type1, Class type2) {
		if (type1 == type2)
			return true;	// They're the same, so assignable.
		if (type1.isPrimitive()) {
			if (type2.isPrimitive()) {
				if (type1 == Boolean.TYPE || type2 == Boolean.TYPE)
					return false;	// Since not equal and one is boolean and the other isn't, not assignable
				int type1Pos = (type1 != Character.TYPE) ? sPrimitivesOrder.indexOf(type1) : sCharPos;
				int type2Pos = (type2 != Character.TYPE) ? sPrimitivesOrder.indexOf(type2) : sCharPos;
				return type1Pos > type2Pos;	// It can be widened if type1 is higher in the order
			}
			return false;	// primitive to non-primitive, not assignable.
		} else
			if (type2 == NULL_TYPE)
				return true;	// NULL_TYPE represents null for us, and null can be assigned to any object
			else		
				return type1.isAssignableFrom(type2);	// Can type2 be assigned to type1
	}
	
	
	/**
	 * Every entry in Array2 can be assigned to the corresponding entry in Array1.
	 */
	public static boolean isAssignableFrom(Class[] types1, Class[] types2) {
		if (types1.length != types2.length)
			return false;	// Not the same size, so not compatible.
		for (int i=0; i<types1.length; i++) {
			if (!isAssignableFrom(types1[i], types2[i]))
				return false;
		}
		return true;	// All are assignable
	}
	
	/**
	 * Return the index of the most compatible method/constructor from the lists passed in.
	 * MethodsList: List of methods (if null then this is for constructors)
	 * ParmsList: List of parms for each method (each entry will be Class[]).
	 */
	private static int findMostCompatible(List methods, List parms, String ambiguousName) throws AmbiguousMethodException {
		// The algorithm used is from the Java Language Specification 15.12.2.2
		// Find the maximally specific ones
		// This is defined as the one that is more specific then all of the rest.
		// If there are duplicates parms that are maximally specific, then it doesn't matter which choosen
		// because when invoked the JVM will make sure the right thing is done.
		// 
		Class[][] parmsCopy = (Class[][]) parms.toArray(new Class[parms.size()][]);
		int size = parmsCopy.length;
		// For each entry see if it is maximally specific, i.e. it is more specific then all of the others.
nextMethod:	for (int i=0; i<size; i++) {
			// For ctors we don't need to test the declaring class because it will always be the same class.
			Class dclClassi = methods != null ? ((Method) methods.get(i)).getDeclaringClass() : null;
			Class[] parmsi = parmsCopy[i];
			for (int j=0; j<size; j++) {
				if (i == j)
					continue;
				// Methodi is more specific if
				//   a) Methodi declaring class is assignable to Methodj declaring class
				//   b) Methodi parms are assignable to Methodj parms
				//
				// First see if Methodi is more specific, if it is
				// then throw out Methodj and continue
				// If Methodi is not compatible to Methodj, go to the next method for i. Methodi is not the most specific
				// Something else is either more specific or none are ma
				if (dclClassi != null) {
					// Step a
					if (!isAssignableFrom(((Method) methods.get(j)).getDeclaringClass(), dclClassi))
						continue nextMethod;	// Methodi is not more specific than Methodj, so try next i.
				}
				
				// Step b
				Class[] parmsj = parmsCopy[j];
				if (!isAssignableFrom(parmsj, parmsi)) {
					// Methodi is not more specific than Methodj, so go to next i.
					continue nextMethod;
				}
			}
			return i;	// Methodi is more specific than all of the other ones.
		}

		throw new AmbiguousMethodException(ambiguousName);	// There was not one more specific than all of the others.
	}
	
	/**
	 * Find the most compatible method for the given arguments.
	 */
	public static Method findCompatibleMethod(Class receiver, String methodName, Class[] arguments) throws NoSuchMethodException, AmbiguousMethodException {
		try {
			Method mthd = receiver.getMethod(methodName, arguments);
			return mthd;	// Found exact match
		} catch (NoSuchMethodException exc) {
			if (arguments != null) {
				// Need to find most compatible one.
				Method mthds[] = receiver.getMethods();
				ArrayList parmsList = new ArrayList(mthds.length); // The parm list from each compatible method.
				ArrayList mthdsList = new ArrayList(mthds.length); // The list of compatible methods, same order as the parms above.
				for (int i = 0; i < mthds.length; i++) {
					Method mthd = mthds[i];
					if (!mthd.getName().equals(methodName))
						continue; // Not compatible, not same name
					Class[] parms = mthd.getParameterTypes();
					if (!isAssignableFrom(parms, arguments))
						continue; // Not compatible, parms
					// It is compatible with the requested method
					parmsList.add(parms);
					mthdsList.add(mthd);
				}

				// Now have list of compatible methods.
				if (parmsList.size() == 0)
					throw throwFixedNoSuchMethod(exc, receiver, methodName, arguments); // None found, so rethrow the exception
				if (parmsList.size() == 1)
					return (Method) mthdsList.get(0); // Only one, so return it

				// Now find the most compatible method
				int mostCompatible = findMostCompatible(mthdsList, parmsList, methodName);
				return (Method) mthdsList.get(mostCompatible);
			} else
				throw throwFixedNoSuchMethod(exc, receiver, methodName, arguments); // None found, so rethrow the exception
		}
	}
	
	/*
	 * NoSuchMEthodExeception doesn't include the signature. Since these are dynamic searches, the exception itself is useless without
	 * the signature. So we add it.
	 */
	private static NoSuchMethodException throwFixedNoSuchMethod(NoSuchMethodException e, Class declareClass, String methodName, Class[] argClasses) {

		// The default trace doesn't show what method was being searched for, so recreate with that.
		StringBuffer s = new StringBuffer();
		s.append(declareClass.getName());
		s.append('.');
		s.append(methodName);
		s.append('(');
		if (argClasses != null) {
			for (int i = 0; i < argClasses.length; i++) {
				if (i > 0)
					s.append(',');
				s.append(argClasses[i].getName());
			}
		}
		s.append(')');
		NoSuchMethodException ne = new NoSuchMethodException(s.toString());
		ne.setStackTrace(e.getStackTrace());
		return ne;
	}
	

	/**
	 * Find the most compatible constructor for the class with the given arguments.
	 * @param receiver class to get the constructor for
	 * @param arguments array of argument types
	 * @return the constructor
	 * @throws NoSuchMethodException no compatible constructor can be found
	 * @throws AmbiguousMethodException there is more than one compatible constructor
	 * @throws IllegalAccessException it can't be accessed. Such as it is a non-static inner class.
	 * 
	 * @since 1.2.0
	 */
	public static Constructor findCompatibleConstructor(Class receiver, Class[] arguments) throws NoSuchMethodException, AmbiguousMethodException, IllegalAccessException {
		if (receiver.getDeclaringClass() != null && !Modifier.isStatic(receiver.getModifiers()))
			throw new IllegalAccessException(MessageFormat.format(Messages.getString("MethodHelper.NONSTATICINNERCLASS_WARNING"), new Object[] {receiver.getName()})); //$NON-NLS-1$
		try {
			java.lang.reflect.Constructor ctor = receiver.getDeclaredConstructor(arguments);
			ctor.setAccessible(true);	// We allow all access, let ide and compiler handle security.
			return ctor;	// Found exact match
		} catch (NoSuchMethodException exc) {
			if (arguments != null) {
				// Need to find most compatible one.
				java.lang.reflect.Constructor ctors[] = receiver.getDeclaredConstructors();
				ArrayList parmsList = new ArrayList(ctors.length); // The parm list from each compatible method.
				ArrayList ctorsList = new ArrayList(ctors.length); // The list of compatible methods, same order as the parms above.
				for (int i = 0; i < ctors.length; i++) {
					java.lang.reflect.Constructor ctor = ctors[i];
					Class[] parms = ctor.getParameterTypes();
					if (!isAssignableFrom(parms, arguments))
						continue; // Not compatible, parms
					// It is compatible with the requested method
					parmsList.add(parms);
					ctorsList.add(ctor);
				}

				// Now have list of compatible methods.
				if (parmsList.size() == 0)
					throw exc; // None found, so rethrow the exception
				if (parmsList.size() == 1) {
					java.lang.reflect.Constructor ctor = (java.lang.reflect.Constructor) ctorsList.get(0); // Only one, so return it
					ctor.setAccessible(true); // We allow all access, let ide and compilor handle security.
					return ctor;
				}

				// Now find the most compatible ctor
				int mostCompatible = findMostCompatible(null, parmsList, receiver.getName());
				java.lang.reflect.Constructor ctor = (java.lang.reflect.Constructor) ctorsList.get(mostCompatible);
				ctor.setAccessible(true); // We allow all access, let ide and compilor handle security.
				return ctor;
			} else
				throw exc; // None found, so rethrow the exception
		}
	}	
				
		
}
