/*******************************************************************************
 * Copyright (c) 2004, 2005 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/

package org.eclipse.jst.jsf.facesconfig.ui.util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageDeclaration;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.ITypeHierarchy;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.ui.JavaUI;
import org.eclipse.jst.jsf.common.ui.IFileFolderConstants;
import org.eclipse.jst.jsf.common.ui.internal.utils.JavaModelUtil;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.PartInitException;

/**
 * This utility class defines typical operations on java class, such as check
 * public constructor, and check type is primitive or not, etc.
 * 
 * @author Jane Cantz, Xiao-guang Zhang
 */
public class JavaClassUtils {
	/**
	 * Determines if a string contains any illegal characters
	 * 
	 * @param text -
	 *            the string to test
	 * @return boolean - true if an illegal character is found, otherwise false
	 */
	public static boolean hasIllegalCharacters(String text) {
		if (text.length() == 0
				|| !Character.isJavaIdentifierStart(text.charAt(0))) {
			return true;
		}
		for (int i = 1; i < text.length(); i++) {
			if (!Character.isJavaIdentifierPart(text.charAt(i))) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Test for constructor.
	 * <p>
	 * This test determines if the class has any constructors
	 * </p>
	 * 
	 * @param methods -
	 *            the IMethod array to examine
	 * @return boolean - true, if method has no constructors
	 */
	public static boolean hasNoConstructor(IMethod[] methods) {
		for (int m = 0; m < methods.length; m++) {
			try {
				if (methods[m].isConstructor()) {
					return false;
				}
			} catch (JavaModelException e) {
                // suppress: this is possible; fall through
			}
		}
		return true;
	}

	/**
	 * check whether the method is public or not.
	 * 
	 * @param method
	 * @return true if method is public
	 */
	public static boolean isPublicMethod(IMethod method) {
		int accessFlags = 0;

		try {
			accessFlags = method.getFlags();
		} catch (JavaModelException e) {
			return false;
		}

		boolean isPublic = Flags.isPublic(accessFlags);
		if ((!Flags.isPrivate(accessFlags))
				&& (!Flags.isProtected(accessFlags))
				&& (!Flags.isPublic(accessFlags))) {
			// No specific modifier was set, so assume to be public
			isPublic = true;
		}
		if (!isPublic) {
			return false;
		}
		return true;
	}

	/**
	 * Test for constructor.
	 * <p>
	 * This test has the following conditions:
	 * </p>
	 * <ul>
	 * <li>method takes 0 arguments and the method name is the class name:
	 * <ul>
	 * <li>takes 0 arguments</li>
	 * <li>the method name is the class name</li>
	 * <li>the method returns void</code></li>
	 * </ul>
	 * </li>
	 * </ul>
	 * 
	 * @param methods -
	 *            the IMethod array to examine
	 * @return boolean - true, if method is a constructor
	 */
	public static boolean hasPublicConstructor(IMethod[] methods) {
		for (int m = 0; m < methods.length; m++) {
			try {
				if (methods[m].isConstructor() && isPublicMethod(methods[m])) {
					// Constructor must have the following 0 arguments
					String[] params = methods[m].getParameterTypes();
					if (params.length == 0) {
						// And must return a void
						String rtn = methods[m].getReturnType();
						if (rtn.equals(Signature.SIG_VOID)) {
							return true;
						}
						break;
					}
				}
			} catch (JavaModelException e) {
				// Nothing to do.
			}
		}
		return false;
	}

	/**
	 * Determines if a datatype is primitive type or part of java.lang or
	 * java.util package. If not, it is considered to be a bean reference
	 * 
	 * @param classType -
	 *            the parent class compilation unit
	 * @param signatureName -
	 *            the datatype of the property
	 * @return boolean - true, if the datatype is primitive or part of java.lang
	 *         or java.util package
	 */
	public static boolean isPrimitiveType(IType classType, String signatureName) {
		while (signatureName.startsWith("[")) { //$NON-NLS-1$
			signatureName = signatureName.substring(1);
		}
		int kind = Signature.getTypeSignatureKind(signatureName);
		if (kind == Signature.BASE_TYPE_SIGNATURE
				|| signatureName.equals(Signature.SIG_VOID)) {
			// These are true primitive types
			return true;
		}

		String qualifiedName = getQualifiedTypeNameInTypeHierarchy(classType,
				signatureName);

		if ((qualifiedName.startsWith("java.lang")) || (qualifiedName.startsWith("java.util"))) //$NON-NLS-1$ //$NON-NLS-2$
		{
			return true;
		}
		return false;
	}

	/**
	 * get the type from the input class name
	 * 
	 * @param project
	 * @param className
	 * @return - can be null.
	 */
	public static IType getType(IProject project, String className) {
		if (project == null) {
			return null;
		}
		IType cunit = null;
		if (className.length() > 0) {

			IJavaProject jProject = JavaCore.create(project);
			try {
				cunit = jProject.findType(className);
			} catch (JavaModelException e) {
                // suppress: fall-through and return null
			}
		}
		return cunit;
	}

	/**
	 * open the type in the editor.
	 * 
	 * @param type
	 * @return true if the type could opened in an editor
	 */
	public static boolean openType(IType type) {
		if (type == null || !type.exists()) {
			return false;
		}

		try {
			IEditorPart editorPart = JavaUI.openInEditor(type
					.getPrimaryElement());
			if (editorPart != null) {
				JavaUI.revealInEditor(editorPart, type.getPrimaryElement());
				return true;
			}
		} catch (PartInitException e) {
			// ignore this error.
		} catch (JavaModelException e) {
			// ignore this error.
		}
		return false;
	}

	/**
	 * get package name from java source file
	 * 
	 * @param javaFile
	 * @return - can be null.
	 */
	public static String getPackageName(IFile javaFile) {
		if (javaFile == null) {
			return null;
		}
		String ext = "." + javaFile.getFileExtension(); //$NON-NLS-1$
		// See if the file is a java file
		if (!ext.equalsIgnoreCase(IFileFolderConstants.EXT_JAVA)) {
			return null;
		}
		String packagename = new String();
		ICompilationUnit cunit = JavaCore.createCompilationUnitFrom(javaFile);
		try {
			IPackageDeclaration[] packages = cunit.getPackageDeclarations();
			if (packages.length == 0) {
				packagename = new String();
			} else {
				packagename = packages[0].getElementName();
			}
		} catch (JavaModelException jme) {
            // suppress: fall-through and return an empty string?? TODO:?
		}
		return packagename;
	}

	/**
	 * copy the array to the list.
	 * 
	 * @param methodList
	 * @param methods
	 */
	private static void copyToMethodList(List methodList, IMethod[] methods) {
		if (methods != null && methods.length > 0) {
			for (int i = 0; i < methods.length; i++) {
				if (!isDuplicateMethod(methodList, methods[i])) {
					methodList.add(methods[i]);
				}
			}
		}
	}

	/**
	 * check whether this method is duplicated or not in the existing method
	 * list.
	 * 
	 * @param methodList
	 * @param method
	 * @return
	 */
	private static boolean isDuplicateMethod(List methodList, IMethod method) {
		if (method == null || !method.exists()) {
			return false;
		}

		String[] paramTypes = method.getParameterTypes();
		String methodName = method.getElementName();

		for (Iterator iter = methodList.iterator(); iter.hasNext();) {
			IMethod existedMethod = (IMethod) iter.next();
			if (isSameMethodSignature(methodName, paramTypes, existedMethod)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * Tests if a method equals to the given signature. Parameter types are only
	 * compared by the simple name, no resolving for the fully qualified type
	 * name is done. Constructors are only compared by parameters, not the name.
	 * 
	 * @param name
	 *            Name of the method
	 * @param paramTypes
	 *            The type signatures of the parameters e.g.
	 *            <code>{"QString;","I"}</code>
	 * @param curr 
	 * @return Returns <code>true</code> if the method has the given name and
	 *         parameter types and constructor state.
	 */
	public static boolean isSameMethodSignature(String name,
			String[] paramTypes, IMethod curr) {
		if (name.equals(curr.getElementName())) {
			String[] currParamTypes = curr.getParameterTypes();
			if (paramTypes.length == currParamTypes.length) {
				for (int i = 0; i < paramTypes.length; i++) {
					String t1 = Signature.getSimpleName(Signature
							.toString(paramTypes[i]));
					String t2 = Signature.getSimpleName(Signature
							.toString(currParamTypes[i]));
					if (!t1.equals(t2)) {
						return false;
					}
				}
				return true;
			}
		}
		return false;
	}

	/**
	 * get methods for the class Type including its super class
	 * 
	 * @param classType
	 * @return - can be null
	 * @throws JavaModelException
	 */
	public static IMethod[] getMethods(IType classType)
			throws JavaModelException {
		if (classType == null) {
			return null;
		}
		List methodList = new ArrayList();
		IMethod[] methods = classType.getMethods();
		copyToMethodList(methodList, methods);

		ITypeHierarchy typeHierarchy = classType.newSupertypeHierarchy(null);

		if (typeHierarchy != null) {
			IType[] superTypes = typeHierarchy.getAllSuperclasses(classType);

			if (superTypes != null && superTypes.length > 0) {
				for (int i = 0; i < superTypes.length; i++) {
					if (!superTypes[i].getFullyQualifiedName().equals(
							"java.lang.Object")) { //$NON-NLS-1$
						methods = superTypes[i].getMethods();

						copyToMethodList(methodList, methods);
					}
				}
			}
		}

		if (methodList != null && methodList.size() > 0) {
			IMethod[] validMethods = (IMethod[]) methodList
					.toArray(new IMethod[methodList.size()]);

			Arrays.sort(validMethods, new Comparator() {
				public int compare(Object o1, Object o2) {
					String name1 = ((IMethod) o1).getElementName();
					String name2 = ((IMethod) o2).getElementName();
					return name1.compareTo(name2);
				}
			});
			return validMethods;
		}
		return null;
	}

	/**
	 * resolve and get the qualified name for the incomplete typename
	 * 
	 * @param classType
	 * @param signatureName
	 * @return - at least equal to Signature.toString(signatureName).
	 */
	public static String getQualifiedTypeNameInTypeHierarchy(IType classType,
			String signatureName) {
		int arrayNum = 0;
		while (signatureName.startsWith("[")) { //$NON-NLS-1$
			arrayNum++;
			signatureName = signatureName.substring(1);
		}

		String qualifiedTypeName = Signature.toString(signatureName);
		int kind = Signature.getTypeSignatureKind(signatureName);
		if (kind == Signature.BASE_TYPE_SIGNATURE
				|| signatureName.equals(Signature.SIG_VOID)) {
			// Add back array identifiers
			while (arrayNum > 0) {
				qualifiedTypeName = qualifiedTypeName + "[]"; //$NON-NLS-1$
				arrayNum--;
			}
			return qualifiedTypeName;
		}

		String typeName = Signature.toString(signatureName);

		String foundName = getQualifiedTypeName(classType, typeName);
		// if found in current type
		if (foundName != null) {
			qualifiedTypeName = foundName;
		} else // else found in the type hierachy.
		{
			ITypeHierarchy typeHierarchy = null;
			try {
				typeHierarchy = classType.newSupertypeHierarchy(null);
			} catch (JavaModelException e) {
				// Nothing to do.
			}
			if (typeHierarchy != null) {
				IType[] superTypes = typeHierarchy.getAllSupertypes(classType);

				if (superTypes != null && superTypes.length > 0) {
					for (int i = 0; i < superTypes.length; i++) {
						if (!superTypes[i].getFullyQualifiedName().equals(
								"java.lang.Object")) { //$NON-NLS-1$
							foundName = getQualifiedTypeName(superTypes[i],
									typeName);
							if (foundName != null) {
								qualifiedTypeName = foundName;
								break;
							}
						}
					}
				}
			}
		}

		// Add back array identifiers
		while (arrayNum > 0) {
			qualifiedTypeName = qualifiedTypeName + "[]"; //$NON-NLS-1$
			arrayNum--;
		}
		return qualifiedTypeName;
	}

	/**
	 * resolve and get the qualified name for the incomplete typename
	 * 
	 * @param classType
	 * @param typeName
	 * @return can be null.
	 */
	public static String getQualifiedTypeName(IType classType, String typeName) {
		String qualifiedTypeName = null;

		try {
			String[][] resolvedNames = classType.resolveType(typeName);
			if (resolvedNames != null && resolvedNames.length > 0) {
				qualifiedTypeName = JavaModelUtil.concatenateName(
						resolvedNames[0][0], resolvedNames[0][1]);
			}
		} catch (JavaModelException e1) {
			// Nothing to do.
		}

		return qualifiedTypeName;
	}

	/**
	 * check whether subclass is sub class of supperclass
	 * 
	 * @param jProject
	 * @param subClass -
	 *            fully qualified name of sub class
	 * @param superClass -
	 *            fully qualified name of super class
	 * 
	 * @return true if subClass is a sub  of  superClass
	 */
	public static boolean isSubClassOf(IJavaProject jProject, String subClass,
			String superClass) {
		if (jProject == null || subClass == null || superClass == null) {
			return false;
		}

		try {
			IType subClassType = jProject.findType(subClass);

			if (subClassType != null) {
				ITypeHierarchy typeHierarchy = null;
				try {
					typeHierarchy = subClassType.newSupertypeHierarchy(null);
				} catch (JavaModelException e) {
					// Nothing to do.
				}
				IType[] superTypes = typeHierarchy
						.getAllSupertypes(subClassType);

				if (superTypes != null && superTypes.length > 0) {
					for (int i = 0; i < superTypes.length; i++) {
						if (superTypes[i].getFullyQualifiedName().equals(
								superClass)) {
							return true;
						}
					}
				}
			}
		} catch (JavaModelException e) {
			// Nothing to do.
		}
		return false;
	}
}
