/*******************************************************************************
 * Copyright (c) 2001, 2006 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.adapters.jdom;
/*
 *  $RCSfile: JDOMSearchHelper.java,v $
 *  $Revision: 1.8 $  $Date: 2006/05/17 20:13:58 $ 
 */

import java.io.File;
import java.util.*;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.*;

import org.eclipse.jem.internal.java.adapters.nls.ResourceHandler;
/**
 * Insert the type's description here.
 * Creation date: (9/26/2001 11:09:30 AM)
 * @author: Administrator
 */
public class JDOMSearchHelper {
	
	private static final String RESOLVED_NAME = " :: RESOLVED_NAME :: "; //$NON-NLS-1$
	private static final String PERIOD = "."; //$NON-NLS-1$
	private static final String BOOLEAN = "boolean"; //$NON-NLS-1$
	private static final String BYTE = "byte"; //$NON-NLS-1$
	private static final String CHAR = "char"; //$NON-NLS-1$
	private static final String SHORT = "short"; //$NON-NLS-1$
	private static final String INT = "int"; //$NON-NLS-1$
	private static final String LONG = "long"; //$NON-NLS-1$
	private static final String FLOAT = "float"; //$NON-NLS-1$
	private static final String DOUBLE = "double"; //$NON-NLS-1$
	private static final String VOID = "void"; //$NON-NLS-1$
	/**
	 * JDOMSearchHelper constructor comment.
	 */
	public JDOMSearchHelper() {
		super();
	}
	/**
	 * If the @simpleName is an inner class, we need to resolve only the declaring class.
	 */
	private static String[][] getTypeNameInfo(IType type, String simpleName, boolean isForReflection) throws JavaModelException {
		String[][] result = null;
		String declaringName, typeName;
		typeName = simpleName;
		if (type != null) {
			if (isForReflection)
				typeName = typeName.replace('.', '$');
			int index = typeName.indexOf("$"); //$NON-NLS-1$
			if (index > 0) {
				declaringName = typeName.substring(0, index);
				result = type.resolveType(declaringName);
				if (result != null) {
					if (isForReflection)
						result[0][1] = result[0][1].replace('.', '$');
					result[0][1] += typeName.substring(index, typeName.length());
				}
			} else {
				index = typeName.indexOf("["); //$NON-NLS-1$
				if (index > 0) {
					declaringName = typeName.substring(0, index);
					result = type.resolveType(declaringName);
					if (result != null)
						result[0][1] = result[0][1] + typeName.substring(index);
				} else
					result = type.resolveType(typeName);
			}
		}
		return result;
	}
	/**
	 * Returns true if the type is a primitive.
	 */
	public final static boolean isPrimitive(String type) {
		return (BOOLEAN.equals(type) || INT.equals(type) || CHAR.equals(type) || SHORT.equals(type) || LONG.equals(type) || FLOAT.equals(type) || DOUBLE.equals(type) || BYTE.equals(type));
	}
	/**
	 * Returns true if the type is a primitive.
	 */
	public final static boolean isPrimitiveOrVoid(String type) {
		return isPrimitive(type) || isVoid(type);
	}
	/**
	 * Returns true if the type is a primitive.
	 */
	public final static boolean isVoid(String type) {
		return VOID.equals(type);
	}
	/**
	 * Returns true if the two signatures match within the scope of the specified type.
	 */
	public static boolean matchTypeSignatures(IType type, String signature1, String signature2) throws JavaModelException {
		return matchTypeSignatures(type, signature1, signature2, null);
	}
	/**
	 * Returns true if the two signatures match within the scope of the specified type.
	 */
	public static boolean matchTypeSignatures(IType type, String signature1, String signature2, Map resolvedNameCache) throws JavaModelException {
		boolean result = false;
		String sig1 = signature1;
		String sig2 = signature2;
		// First check array count.
		if (Signature.getArrayCount(sig1) == Signature.getArrayCount(sig2)) {
			// We have the same array count, get the element types for consideration.
			sig1 = Signature.getElementType(sig1);
			sig2 = Signature.getElementType(sig2);

			// There are three cases:
			//		1) Both are unqualified (both being primitive will fall into this),
			//		2) Both are qualified, and
			//		3) One is qualified and the other is not (one could be primitive).

			// For the first two cases a compare of the readable names will always do.
			if (!((sig1.indexOf('.') == -1) ^ (sig2.indexOf('.') == -1))) {
				result = Signature.toString(sig1).equals(Signature.toString(sig2));
			} else {
				// This is case 3.
				// First root out one being primitive.
				if (((sig1.charAt(0) == 'Q') || (sig1.charAt(0) == 'L')) && ((sig2.charAt(0) == 'Q') || (sig2.charAt(0) == 'L'))) {
					// Get the readable name of the qualified signature
					// and the simple name of the other.
					String qualifiedName = null;
					String simpleName = null;
					if (sig1.indexOf('.') == -1) {
						qualifiedName = Signature.toString(sig2);
						simpleName = Signature.toString(sig1);
					} else {
						qualifiedName = Signature.toString(sig1);
						simpleName = Signature.toString(sig2);
					}

					// If the simple name resolves to the qualified name, we have a match.
					result = qualifiedName.equals(resolveSimpleTypeName(type, simpleName, resolvedNameCache));
				}
			}
		}

		return result;
	}
	private static boolean needsToResolveName(IType type, String simpleName, boolean isForReflection) {
		return !(type.isBinary() || (!isForReflection && simpleName.indexOf(PERIOD) > -1) || isPrimitiveOrVoid(simpleName));
	}
	/**
	 * Returns the qualified name for the simple name within the scope of the type.
	 * Returns null if the name can not be resolved.
	 */
	public static String resolveSimpleTypeName(IType type, String simpleName) throws JavaModelException {
		return resolveSimpleTypeName(type, simpleName, null);
	}
	/**
	 * Returns the qualified name for the simple name within the scope of the type.
	 * Returns null if the name can not be resolved.
	 */
	public static String resolveSimpleTypeName(IType type, String simpleName, Map resolvedNameCache) throws JavaModelException {
		return resolveSimpleTypeName(type, simpleName, resolvedNameCache, false);
	}

	/**
	 * Returns the qualified name for the simple name within the scope of the type.
	 * Returns null if the name can not be resolved.
	 */
	public static String resolveSimpleTypeName(IType type, String simpleName, Map resolvedNameCache, boolean isForReflection) throws JavaModelException {
		if (!needsToResolveName(type, simpleName, isForReflection))
			return simpleName;
		String key = null, qualifiedName = null;
		if (resolvedNameCache != null) {
			key = type.getFullyQualifiedName() + RESOLVED_NAME + simpleName;
			qualifiedName = (String) resolvedNameCache.get(key);
		}
		if (qualifiedName == null) {
			String[][] result = getTypeNameInfo(type, simpleName, isForReflection);
			if (result != null) {
				String packName = result[0][0];
				if (packName.length() == 0) {
					qualifiedName = result[0][1];
					if (isForReflection)
						qualifiedName = qualifiedName.replace('.', '$');					
				} else {
					StringBuffer b = new StringBuffer();
					b.append(result[0][0]).append(PERIOD);
					String typeName = result[0][1];
					if (isForReflection)
						typeName = typeName.replace('.', '$');
					b.append(typeName);
					qualifiedName = b.toString();
				}
			} else {
				qualifiedName = simpleName;
			}
			if (resolvedNameCache != null)
				resolvedNameCache.put(key, qualifiedName);
		}
		return qualifiedName;
	}
	/**
	 * Searches for a matching method and sets it in the
	 * descriptor if found.
	 */
	public static IMethod searchForMatchingMethod(IType type, String methodName, String[] parmSigs) throws JavaModelException {
		return searchForMatchingMethod(type, methodName, parmSigs, null);
	}
	/**
	 * Searches for a matching method and sets it in the
	 * descriptor if found.
	 */
	public static IMethod searchForMatchingMethod(IType type, String methodName, String[] parmSigs, Map resolvedNameCache) throws JavaModelException {

		// First get all the methods by this name and with this many parms.
		IMethod[] allMethods = type.getMethods();
		List candidateMethods = new ArrayList();
		for (int i = 0; i < allMethods.length; i++) {
			int parmSigsLength = (parmSigs != null ? parmSigs.length : 0);
			if ((allMethods[i].getElementName().equals(methodName)) && (allMethods[i].getNumberOfParameters() == parmSigsLength))
				candidateMethods.add(allMethods[i]);
		}

		// For each candidate consider each parm for a match.
		// Take the first one that matches on all parms.
		IMethod next = null;
		String[] nextParmSigs = null;
		boolean found = false;
		Iterator candidateIter = candidateMethods.iterator();
		while (!found && (candidateIter.hasNext())) {
			next = (IMethod) candidateIter.next();
			nextParmSigs = next.getParameterTypes();
			found = true;
			for (int i = 0;(found && (i < nextParmSigs.length)); i++)
				found &= matchTypeSignatures(type, parmSigs[i], nextParmSigs[i], resolvedNameCache);
		}
		return found ? next : null;
	}

	/**
	* The returned Object[] will contain two entries.  The
	* first will be the IJavaElement that was found and the
	* second will be the qualifiedName used to find it.
	*/
	protected static Object[] findActualJavaElement(String qualifiedName, IJavaProject javaProject, JDOMAdaptor adaptor) {
		Object[] result = new Object[2];
		if (adaptor == null)
			result[1] = qualifiedName;
		else 
			//Ensure the name is qualified
			result[1] = getResolvedTypeName(qualifiedName, adaptor.getType(), adaptor.getTypeResolutionCache());
		
		result[0] = findJavaElement((String) result[1], javaProject, adaptor);
		if (result[0] == null)
			findInnerJavaElement(result, javaProject, adaptor);
		return result;
	}

	/**
	 * The returned Object[] will contain two entries.  The
	 * first will be the IJavaElement that was found and the
	 * second will be the qualifiedName used to find it.
	 */
	protected static void findInnerJavaElement(Object[] info, IJavaProject javaProject, JDOMAdaptor adaptor) {
		String qualifiedName, innerName;
		qualifiedName = (String) info[1];
		int index = qualifiedName.lastIndexOf("."); //$NON-NLS-1$
		if (index > 0) {
			innerName = qualifiedName.substring(0, index);
			innerName += "$"; //$NON-NLS-1$
			innerName += qualifiedName.substring(index + 1, qualifiedName.length());
			if (adaptor != null) {
				//Ensure the name is qualified which it may not be if an inner class
				innerName = getResolvedTypeName(innerName, adaptor.getType(), adaptor.getTypeResolutionCache());
			}
			info[1] = innerName;
			info[0] = findJavaElement(innerName, javaProject, adaptor);
			if (info[0] == null)
				findInnerJavaElement(info, javaProject, adaptor);
		}
	}

	protected static IJavaElement findJavaElement(String qualifiedName, IJavaProject javaProject, JDOMAdaptor adaptor) {
		try {
			if (javaProject != null) {
				return javaProject.findType(qualifiedName);
			}
		} catch (JavaModelException jme) {
			System.out.println(ResourceHandler.getString("Error_Looking_Up_Type_ERROR_", (new Object[] { qualifiedName, jme.getMessage()}))); //$NON-NLS-1$ = "Error looking up type: "
		}
		return null;
	}
	
	protected static IPath getPathFromQualifiedName(String qualifiedName) {
		return new Path(qualifiedName.replace('.', File.separatorChar) + ".java"); //$NON-NLS-1$
	}
	/* 
	* Resolve a type name in the context of a Type.
	* (Borrowed from org.eclipse.jdt.ui.codemanipulation.StubUtility.getResolvedTypeName())
	* The input is a simple or qualified name, NOT a signature
	* The output will be a qualified name, NOT a signature
	*/
	public static String getResolvedTypeName(String typeName, IType declaringType, Map typeCache) {
		String name = typeName;
		try {
			name = JDOMSearchHelper.resolveSimpleTypeName(declaringType, typeName, typeCache, true);
		} catch (JavaModelException e) {
			// ignore
		}
		return name;
	}

	public static IType findType(String qualifiedName, boolean useAdvancedForInners, IJavaProject javaProject, JDOMAdaptor adaptor) {
		try {
			IJavaElement found = null;
			String resolvedName = qualifiedName;
			if (useAdvancedForInners) {
				Object[] result = findActualJavaElement(qualifiedName, javaProject, adaptor);
				found = (IJavaElement) result[0];
				resolvedName = (String) result[1];
			} else
				found = findJavaElement(qualifiedName, javaProject, adaptor);
			if (found != null)
				if (found instanceof IClassFile)
					return ((IClassFile) found).getType();
				else if (found instanceof ICompilationUnit) {
					ICompilationUnit foundCU = (ICompilationUnit) found;
					// strip the ".java", lifted from CompilationUnit.getMainTypeName()
					String cuMainTypeName = foundCU.getElementName();
					cuMainTypeName = cuMainTypeName.substring(0, cuMainTypeName.length() - 5);
					return foundCU.getType(cuMainTypeName);
				} else if (found instanceof IType) {
					IType type = ((IType) found);
					if (!type.getFullyQualifiedName('$').equals(resolvedName)) {
						// I don't know why this is here. Sometime in the past for an inner class, the
						// IType returned was for the outer class, so you would need to search again
						// for the inner class against the outer class. I don't know how this now can
						// happen. The code followed above is extremelly complicated, especially when
						// it is an inner class that isn't fully-qualified that is inside a source file.
						// It goes through some gyrations for that. I don't know what it would
						// return in that case. But just in case, the test is here to be safe.
						int index = resolvedName.lastIndexOf('$'); //$NON-NLS-1$
						if (index > -1)
							return type.getType(resolvedName.substring(index + 1, resolvedName.length()));
						else
							return type;
					} else
						return type;
				}
		} catch (JavaModelException jme) {
			System.out.println(ResourceHandler.getString("Error_Looking_Up_Type_ERROR_", (new Object[] { qualifiedName, jme.getMessage()}))); //$NON-NLS-1$ = "Error looking up type: "
		}
		return null;
	}
	
	public static IType findType(String packageName, String qualifiedTypeName, IJavaProject javaProject) {
		try {
			if (javaProject != null) {
				return javaProject.findType(packageName, qualifiedTypeName.replace('$', '.'));
			}
		} catch (JavaModelException jme) {
			System.out.println(ResourceHandler.getString("Error_Looking_Up_Type_ERROR_", (new Object[] { packageName + "." + qualifiedTypeName, jme.getMessage()}))); //$NON-NLS-1$ //$NON-NLS-2$ = "Error looking up type: "
		}
		return null;
	}

}
