/*******************************************************************************
 * 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.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 java.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>
 * 
 * @author pavery
 */
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;
					else
						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;
				}
				else {
					// 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;
	}
}