/*******************************************************************************
 * Copyright (c) 2004 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.jst.jsp.ui.internal.contentassist;

import java.beans.Introspector;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import com.ibm.icu.util.StringTokenizer;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.QualifiedName;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
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.jst.jsp.ui.internal.Logger;

/**
 * Navigates the IJavaProject classpath (incl. source) on a given resource and infers bean properties
 * given a fully qualified beanname. Bean properties can be retrieved using:
 * <code>getRuntimeProperties(IResource baseResource, String typeName)</code>
 * 
 * @plannedfor 1.0
 */
public class BeanInfoProvider implements IBeanInfoProvider {

	public class JavaPropertyDescriptor implements IJavaPropertyDescriptor {
		String fType = null;
		String fName = null;
		boolean fReadable = true;
		boolean fWritable = true;

		public JavaPropertyDescriptor(String name, String type, boolean readable, boolean writable) {
			fName = name;
			fType = type;
			fReadable = readable;
			fWritable = writable;
		}

		public String getDeclaredType() {
			return fType;
		}

		public String getDisplayName() {
			return fName;
		}

		public String getName() {
			return fName;
		}

		public boolean getReadable() {
			return fReadable;
		}

		public boolean getWriteable() {
			return fWritable;
		}
	}

	// looks up encoded type (see Class.getName), and gives you a displayable string
	private HashMap fEncodedTypeMap = null;
	// to avoid repeat properties from showing up
	private HashSet fRepeatMethods = null;

	public BeanInfoProvider() {
		fRepeatMethods = new HashSet();
	}

	/**
	 * Returns the inferred properties of a bean based on the project from the baseResource,
	 * and the fully qualified name of the bean.
	 * 
	 * @param baseResource the base resource where the bean is being used
	 * @param typeName the <i>fully qualified</i> type name (eg. javax.swing.JButton) of the bean
	 */
	public IJavaPropertyDescriptor[] getRuntimeProperties(IResource baseResource, String typeName) {
		IJavaProject javaProject = JavaCore.create(baseResource.getProject());
		QualifiedName typeQualifiedName = getTypeQualifiedName(typeName);
		List getMethodResults = new ArrayList();
		List isMethodResults = new ArrayList();
		List setMethodResults = new ArrayList();
		List descriptorResults = new ArrayList();
		try {
			IType type = javaProject.findType(typeQualifiedName.getQualifier() + "." + typeQualifiedName.getLocalName()); //$NON-NLS-1$
			// type must exist
			if(type != null) {
				ITypeHierarchy hierarchy = type.newTypeHierarchy(null);
				IType[] supers = hierarchy.getAllSuperclasses(type);
	
				IMethod[] methods = type.getMethods();
				// iterate the bean's methods
				for (int i = 0; i < methods.length; i++)
					acceptMethod(getMethodResults, isMethodResults, setMethodResults, methods[i]);
				// the bean hierarchy's methods
				for (int i = 0; i < supers.length; i++) {
					methods = supers[i].getMethods();
					for (int j = 0; j < methods.length; j++)
						acceptMethod(getMethodResults, isMethodResults, setMethodResults, methods[j]);
				}
				adaptMethodsToPropertyDescriptors(getMethodResults, isMethodResults, setMethodResults, descriptorResults);
			}
		}
		catch (JavaModelException jmex) {
			Logger.logException("Problem navigating JavaProject in BeanInfoProvider", jmex); //$NON-NLS-1$
		}

		IJavaPropertyDescriptor[] finalResults = new IJavaPropertyDescriptor[descriptorResults.size()];
		System.arraycopy(descriptorResults.toArray(), 0, finalResults, 0, descriptorResults.size());
		return finalResults;
	}

	/**
	 * Retrieves the necessary information from method declaration lists, creates and fills a list of JavaPropertyDescriptors.
	 * @param getMethods
	 * @param isMethods
	 * @param setMethods
	 * @param descriptorResults
	 */
	private void adaptMethodsToPropertyDescriptors(List getMethods, List isMethods, List setMethods, List descriptors) throws JavaModelException {
		List readable = new ArrayList();
		HashMap types = new HashMap();

		// iterate through get* and is* methods, updating 'readable' list and 'types' map
		filterGetMethods(getMethods, readable, types);
		filterIsMethods(isMethods, readable, types);

		// iterate set* methods, checking overlap w/ readable
		Iterator it = setMethods.iterator();
		IMethod temp = null;
		String name = ""; //$NON-NLS-1$
		String type = ""; //$NON-NLS-1$
		String[] encodedParams = null;
		String returnType = ""; //$NON-NLS-1$
		String param0 = ""; //$NON-NLS-1$

		while (it.hasNext()) {
			temp = (IMethod) it.next();
			name = createPropertyNameFromMethod(temp);
			// invalid naming convention
			if (name == null)
				continue;

			returnType = getDecodedTypeName(temp.getReturnType());
			// setter should have no return type
			if (!returnType.equals("void")) //$NON-NLS-1$
				continue;

			// need to get type from parameter
			encodedParams = temp.getParameterTypes();
			if (encodedParams != null && encodedParams.length > 0) {
				if (encodedParams.length > 1) {
					// multiple params
					param0 = getDecodedTypeName(encodedParams[0]);
					if (!param0.equals("int")) //$NON-NLS-1$
						// not a valid indexed property
						continue;
					
					type = getDecodedTypeName(encodedParams[1]);
				}
				else {
					// one param, regular setter
					if (isArray(encodedParams[0]))
						type = getDecodedTypeName(encodedParams[0]);
				}
			}

			if (readable.contains(name)) {
				// writable and readable
				if (!fRepeatMethods.contains(name)) {
					descriptors.add(new JavaPropertyDescriptor(name, (String) types.get(name), true, true));
					readable.remove(name);
					fRepeatMethods.add(name);
				}
			}
			else {
				// wasn't readable, just writable
				String[] params = temp.getParameterTypes();
				// can't be setProperty if no parameters
				if (!(params.length > 0))
					continue;
				if (!fRepeatMethods.contains(name)) {
					type = getDecodedTypeName(params[0]);
					descriptors.add(new JavaPropertyDescriptor(name, type, false, true));
					fRepeatMethods.add(name);
				}
			}
		}
		// add leftover from readable, get* and is* methods (readable = true, writable = false)
		it = readable.iterator();
		while (it.hasNext()) {
			name = (String) it.next();
			if (!fRepeatMethods.contains(name)) {
				descriptors.add(new JavaPropertyDescriptor(name, (String) types.get(name), true, false));
				fRepeatMethods.add(name);
			}
		}
	}

	private void filterGetMethods(List getMethods, List readable, HashMap types) throws JavaModelException {
		IMethod temp;
		String name;
		String encodedReturnType;
		String returnType;
		Iterator it = getMethods.iterator();
		String[] encodedParams;
		String paramType;
		// iterate get* methods
		while (it.hasNext()) {
			temp = (IMethod) it.next();
			name = createPropertyNameFromMethod(temp);
			// invalid bean naming convention
			if (name == null)
				continue;

			encodedReturnType = temp.getReturnType();
			returnType = getDecodedTypeName(encodedReturnType);

			//  can't get be a getProperty if returns void
			if (returnType.equals("void")) //$NON-NLS-1$
				continue;

			// check params in case it's indexed propety
			encodedParams = temp.getParameterTypes();
			if (encodedParams != null && encodedParams.length == 1) {
				paramType = getDecodedTypeName(encodedParams[0]);
				// syntax is > Type getter(int);
				if (!paramType.equals("int")) { //$NON-NLS-1$
					//it's not an indexed property
					continue;
				}
				// it is indexed, prop type is an ARRAY
				returnType += "[]"; //$NON-NLS-1$
			}

			readable.add(name);
			types.put(name, returnType);
		}

	}

	private void filterIsMethods(List isMethodResults, List readable, HashMap types) throws JavaModelException {
		IMethod temp;
		String name;
		String encodedReturnType;
		String returnType;
		String[] encodedParams;
		String paramType;
		// iterate is* methods
		Iterator it = isMethodResults.iterator();
		while (it.hasNext()) {
			temp = (IMethod) it.next();
			name = createPropertyNameFromMethod(temp);
			// invalid bean naming convention
			if (name == null)
				continue;
			encodedReturnType = temp.getReturnType();
			returnType = getDecodedTypeName(encodedReturnType);

			// isProperty only valid for boolean
			if (!returnType.equals("boolean")) //$NON-NLS-1$
				continue;

			// check params in case it's indexed propety
			encodedParams = temp.getParameterTypes();
			if (encodedParams != null && encodedParams.length == 1) {
				paramType = getDecodedTypeName(encodedParams[0]);
				// syntax is > Type getter(int);
				if (!paramType.equals("int")) { //$NON-NLS-1$
					//it's not a valid indexed property
					continue;
				}
			}

			readable.add(name);
			types.put(name, returnType);
		}
	}

	/**
	 * Pass in a get*|set*|is* method and it will return an inferred property name using <code>Introspector.decapitalize(String)</code>
	 * @param temp
	 * @return an inferred property name based on the IMethod name, null if the name is not valid according to bean spec
	 */
	private String createPropertyNameFromMethod(IMethod temp) {
		String name = temp.getElementName();
		if (name.startsWith("is")) //$NON-NLS-1$
			name = Introspector.decapitalize(name.substring(2));
		else
			// must be get or set
			name = Introspector.decapitalize(name.substring(3));
		return name;
	}

	/**
	 * Initial filtering of methods.  Checks prefix if it's valid length.  If the prefix is "get" the  method name 
	 * is placed in the getMethodResults List.  If the prefix is "is", the name is added to the isMethodResults list.  If the
	 * prefix is "set", it's added to the setMethodResultsList.
	 * 
	 * @param getMethodResults
	 * @param isMethodResults
	 * @param setMethodResults
	 * @param method
	 */
	private void acceptMethod(List getMethodResults, List isMethodResults, List setMethodResults, IMethod method) throws JavaModelException {
		if (!fRepeatMethods.contains(method.getElementName())) {
			fRepeatMethods.add(method.getElementName());
			int flags = method.getFlags();
			String methodName = method.getElementName();
			if (Flags.isPublic(flags)) {
				if (methodName.length() > 3 && methodName.startsWith("get")) //$NON-NLS-1$
					getMethodResults.add(method);
				else if (methodName.length() > 2 && methodName.startsWith("is")) //$NON-NLS-1$
					isMethodResults.add(method);
				else if (methodName.length() > 3 && methodName.startsWith("set")) //$NON-NLS-1$
					setMethodResults.add(method);
			}
		}
	}

	/**
	 * @param typeName
	 * @return a Qualified name with the package as the qualifier, and class name as LocalName
	 */
	private QualifiedName getTypeQualifiedName(String typeName) {
		StringTokenizer st = new StringTokenizer(typeName, ".", false); //$NON-NLS-1$
		int length = st.countTokens();
		int count = 0;
		StringBuffer root = new StringBuffer();
		while (count++ < length - 1) {
			root.append(st.nextToken());
			if (count < length - 1)
				root.append('.');
		}
		return new QualifiedName(root.toString(), st.nextToken());
	}

	/**
	 * Checks if encodedTypeName is an array
	 * @param encodedTypeName
	 * @return true if encodedTypeName is an array, false otherwise.
	 */
	private boolean isArray(String encodedTypeName) {
		if (encodedTypeName != null && encodedTypeName.length() > 0) {
			if (encodedTypeName.charAt(0) == '[')
				return true;
		}
		return false;
	}

	/**
	 * Returns the decoded (displayable) name fo the type.
	 * Either a primitive type (int, long, float...) Object (String)
	 * @param type
	 * @return decoded name for the encoded string
	 */
	private String getDecodedTypeName(String encoded) {
		HashMap map = getEncodedTypeMap();

		StringBuffer decoded = new StringBuffer();
		char BRACKET = '[';
		String BRACKETS = "[]"; //$NON-NLS-1$
		char identifier = ' ';
		int last = 0;
		// count brackets
		while (encoded.indexOf(BRACKET, last) != -1) {
			last++;
		}
		identifier = encoded.charAt(last);
		Object primitiveType = map.get(String.valueOf(identifier));
		// L > binary type name, Q > source type name
		if (identifier == 'L' || identifier == 'Q') {
			// handle object
			String classname = encoded.substring(last + 1, encoded.length() - 1);
			decoded.append(classname);
		}
		else if (primitiveType != null) {
			// handle primitive type (from IField.getSignature())
			decoded.append((String) primitiveType);
		}
		else {
			// handle primitive type (from Class.getName())
			decoded.append(encoded);
		}
		// handle arrays
		if (last > 0) {
			for (int i = 0; i < last; i++) {
				decoded.append(BRACKETS);
			}
		}
		return decoded.toString();
	}

	/**
	 *	from Class.getName() javadoc
	 *	also see Signature in jdt.core api
	 *<pre>
	 *			B            byte
	 *			C            char
	 *			D            double
	 *			F            float
	 *			I            int
	 *			J            long
	 *			Lclassname;  class or interface
	 *			Qsourcename; source
	 *			S            short
	 *			Z            boolean
	 *			V	   		 void
	 *</pre>
	 *
	 * @return the "encoding letter" to "type" map.
	 */
	private HashMap getEncodedTypeMap() {
		if (fEncodedTypeMap == null) {
			fEncodedTypeMap = new HashMap();
			fEncodedTypeMap.put("B", "byte"); //$NON-NLS-1$ //$NON-NLS-2$
			fEncodedTypeMap.put("C", "char"); //$NON-NLS-1$ //$NON-NLS-2$
			fEncodedTypeMap.put("D", "double"); //$NON-NLS-1$ //$NON-NLS-2$
			fEncodedTypeMap.put("F", "float"); //$NON-NLS-1$ //$NON-NLS-2$
			fEncodedTypeMap.put("I", "int"); //$NON-NLS-1$ //$NON-NLS-2$
			fEncodedTypeMap.put("J", "long"); //$NON-NLS-1$ //$NON-NLS-2$
			fEncodedTypeMap.put("S", "short"); //$NON-NLS-1$ //$NON-NLS-2$
			fEncodedTypeMap.put("Z", "boolean"); //$NON-NLS-1$ //$NON-NLS-2$
			fEncodedTypeMap.put("V", "void"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return fEncodedTypeMap;
	}
}
