/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.click.eclipse.ui.editor;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;


import org.apache.click.eclipse.ClickUtils;
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.JavaModelException;
import org.eclipse.jdt.core.Signature;

/**
 * Provides accessors which are easy to use for JDT class model.
 * This class would be used by the code completion in the Velocity editor.
 * 
 * @author Naoki Takezoe
 * @see TemplateContentAssistProcessor
 */
public class TemplateObject {
	
	private IType type;
	private String primitiveType;
	
	/**
	 * The constructor.
	 * 
	 * @param type the <code>IType</code> object
	 */
	public TemplateObject(IType type){
		this.type = type;
	}
	
	/**
	 * The constructor for primitive types.
	 * 
	 * @param primitiveType the primitive type name
	 */
	public TemplateObject(String primitiveType){
		this.primitiveType = primitiveType;
	}
	
	/**
	 * Returns the specified method.
	 * If this object doesn't have the specified method, returns <code>null</code>.
	 * 
	 * @param name the method name
	 * @return the specified method or <code>null</code>
	 */
	public TemplateObjectMethod getMethod(String name){
		if(this.type!=null){
			TemplateObjectMethod[] methods = getMethods();
			for(int i=0;i<methods.length;i++){
				if(methods[i].getName().equals(name)){
					return methods[i];
				}
			}
		}
		return null;
	}
	
	/**
	 * Returns the specified property.
	 * If this object doesn't have the specified property, returns <code>null</code>.
	 * 
	 * @param name the property name
	 * @return the specified property or <code>null</code>
	 */
	public TemplateObjectProperty getProperty(String name){
		if(this.type!=null){
			TemplateObjectProperty[] properties = getProperties();
			for(int i=0;i<properties.length;i++){
				if(properties[i].getName().equals(name)){
					return properties[i];
				}
			}
		}
		return null;
	}
	
	/**
	 * Returns available methods in this object.
	 * 
	 * @return the array of methods
	 */
	public TemplateObjectMethod[] getMethods(){
		if(this.type!=null){
			try {
				IMethod[] methods = getAllMethods(type);
				List<TemplateObjectMethod> result = new ArrayList<TemplateObjectMethod>();
				for(int i=0;i<methods.length;i++){
					if(Flags.isPublic(methods[i].getFlags()) && !methods[i].isConstructor()){
						result.add(new TemplateObjectMethod(methods[i]));
					}
				}
				return result.toArray(new TemplateObjectMethod[result.size()]);
			} catch (JavaModelException e) {
			}
		}
		return new TemplateObjectMethod[0];
	}
	
	/**
	 * Returns available fields in this object.
	 * 
	 * @return the array of properties
	 */
	public TemplateObjectProperty[] getProperties(){
		if(this.type!=null){
			try {
				IMethod[] methods = getAllMethods(type);
				List<TemplateObjectProperty> result = new ArrayList<TemplateObjectProperty>();
				for(int i=0;i<methods.length;i++){
					if(Flags.isPublic(methods[i].getFlags()) && methods[i].getParameterTypes().length==0){
						String name = methods[i].getElementName();
						if((name.startsWith("get") && name.length() > 3) || 
								(name.startsWith("is") && name.length() > 2)){
							result.add(new TemplateObjectProperty(methods[i]));
						}
					}
				}
				return result.toArray(new TemplateObjectProperty[result.size()]);
			} catch (JavaModelException e) {
			}
		}
		return new TemplateObjectProperty[0];
	}
	
	/**
	 * Returns available methods and fields in this object.
	 * 
	 * @return the array of both methods and properties
	 */
	public TemplateObjectElement[] getChildren(){
		List<TemplateObjectElement> result = new ArrayList<TemplateObjectElement>();
		if(this.type!=null){
			TemplateObjectMethod[] methods = getMethods();
			TemplateObjectProperty[] properties = getProperties();
			for(int i=0;i<methods.length;i++){
				result.add(methods[i]);
			}
			for(int i=0;i<properties.length;i++){
				result.add(properties[i]);
			}
			Collections.sort(result, new Comparator<TemplateObjectElement>(){
				public int compare(TemplateObjectElement arg0, TemplateObjectElement arg1) {
					return arg0.toString().compareTo(arg1.toString());
				}
			});
		}
		return (TemplateObjectElement[])result.toArray(new TemplateObjectElement[result.size()]);
	}
	
	/**
	 * Tests whether this object is the primitive type.
	 * 
	 * @return <code>true</code> if this is the primitive type; 
	 *   <code>false</code> otherwise
	 */
	public boolean isPrimitive(){
		return this.type == null;
	}
	
	/**
	 * Returns the <code>IType</code> instance of this object.
	 * 
	 * @return the <code>IType</code> instance.
	 *   If this object is the primitive type, returns null.
	 */
	public IType getType(){
		return this.type;
	}
	
	/**
	 * Returns the type name of this object.
	 * 
	 * @return the full qualified class name or the primitive type name
	 */
	public String getTypeName(){
		if(this.type!=null){
			return this.type.getFullyQualifiedName();
		} else {
			return this.primitiveType;
		}
	}
	
	///////////////////////////////////////////////////////////////////////////////////////
	//
	// Inner Classes
	//
	///////////////////////////////////////////////////////////////////////////////////////
	/**
	 * The <code>TemplateObjectElement</code> implementation which expresses
	 * the proprty of <code>TemplateObject</code>
	 */
	public static class TemplateObjectProperty implements TemplateObjectElement {
		
		private IMethod method;
		
		public TemplateObjectProperty(IMethod method){
			this.method = method;
		}
		
		public String getName(){
			String name = this.method.getElementName();
			if(name.startsWith("get")){
				name = name.substring(3);
			} else if(name.startsWith("is")){
				name = name.substring(2);
			}
			return name.substring(0, 1).toLowerCase() + name.substring(1);
		}
		
		public String getDisplayName(){
			StringBuffer sb = new StringBuffer();
			sb.append(getName());
			sb.append(" ");
			try {
				sb.append(getSimpleName(Signature.toString(this.method.getReturnType())));
			} catch(Exception ex){
			}
			sb.append(" - ");
			sb.append(this.method.getDeclaringType().getElementName());
			return sb.toString();
		}
		
		/**
		 * Returns the <code>TemplateObject</code> by the property type.
		 */
		public TemplateObject toTemplateObject(){
			try {
				String className = ClickUtils.removeTypeParameter(Signature.toString(this.method.getReturnType()));
				if(ClickUtils.isPrimitive(className)){
					return null;
				}
				className = ClickUtils.resolveClassName(method.getDeclaringType(), className);
				IJavaProject javaProject = method.getDeclaringType().getJavaProject();
				IType type = javaProject.findType(className);
				if(type!=null && type.exists()){
					return new TemplateObject(type);
				}
			} catch(Exception ex){
			}
			return null;
		}
		
		public String toString(){
			return getDisplayName();
		}
	}
	
	/**
	 * The <code>TemplateObjectElement</code> implementation which expresses
	 * the method of <code>TemplateObject</code>
	 */
	public static class TemplateObjectMethod implements TemplateObjectElement {
		
		private IMethod method;
		
		public TemplateObjectMethod(IMethod method){
			this.method = method;
		}
		
		public String getName(){
			return this.method.getElementName();
		}
		
//		public int getArgumentCount(){
//			return this.method.getParameterTypes().length;
//		}
		
		public String getDisplayName(){
			StringBuffer sb = new StringBuffer();
			sb.append(getName());
			sb.append("(");
			String[] types = this.method.getParameterTypes();
			String[] names = null;
			try {
				names = this.method.getParameterNames();
			} catch(Exception ex){
				names = new String[types.length];
				for(int i=0;i<names.length;i++){
					names[i] = "arg" + i;
				}
			}
			for(int i=0;i<types.length;i++){
				if(i != 0){
					sb.append(", ");
				}
				sb.append(getSimpleName(Signature.toString(types[i])));
				sb.append(" ");
				sb.append(names[i]);
			}
			sb.append(") ");
			try {
				sb.append(getSimpleName(Signature.toString(method.getReturnType())));
			} catch(Exception ex){
			}
			sb.append(" - ");
			sb.append(method.getDeclaringType().getElementName());
			return sb.toString();
		}
		
		/**
		 * Returns the <code>TemplateObject</code> by the return type of the method.
		 */
		public TemplateObject toTemplateObject(){
			// TODO This implementation is same to TemplateObjectProperty.
			try {
				String className = ClickUtils.removeTypeParameter(Signature.toString(this.method.getReturnType()));
				if(ClickUtils.isPrimitive(className)){
					return null;
				}
				className = ClickUtils.resolveClassName(method.getDeclaringType(), className);
				IJavaProject javaProject = method.getDeclaringType().getJavaProject();
				IType type = javaProject.findType(className);
				if(type!=null && type.exists()){
					return new TemplateObject(type);
				}
			} catch(Exception ex){
			}
			return null;
		}
		
		public String toString(){
			return getDisplayName();
		}
	}
	
	/**
	 * The interface of <code>TemplateObject</code> elements,
	 * expresses methods and properties.
	 */
	public static interface TemplateObjectElement {
		
		/**
		 * Returns the element name.
		 * 
		 * @return the element name
		 */
		public String getName();
		
		/**
		 * Returns the display string.
		 * 
		 * @return the display string which might contain type names or parameters
		 */
		public String getDisplayName();
		
		/**
		 * Converts this object to the <code>TemplateObject</code>.
		 * <p>
		 * For example, if the instance corresponds a method,
		 * this method would return the <code>TemplateObject</code> of 
		 * the method return type.
		 * 
		 * @return the <code>TemplateObject</code> instance or <code>null</code>
		 */
		public TemplateObject toTemplateObject();
	}
	
	///////////////////////////////////////////////////////////////////////////////////////
	//
	// Utility methods
	//
	///////////////////////////////////////////////////////////////////////////////////////
	
	/**
	 * Get the simple classname from the full qualified classname.
	 * 
	 * @param name the full qualified classname
	 * @return the simple classname
	 */
	private static String getSimpleName(String name){
		String simpleName = ClickUtils.removeTypeParameter(name);
		if(simpleName.indexOf('.')>=0){
			simpleName = simpleName.substring(simpleName.lastIndexOf('.') + 1);
		}
		return simpleName;
	}
	
	/**
	 * Returns all public methods of the given type.
	 * 
	 * @param type the <code>IType</code> instance
	 * @return all methods of the given type, not contains main method and constructor
	 * @throws JavaModelException
	 */
	private static IMethod[] getAllMethods(IType type) throws JavaModelException {
		ArrayList<IMethod> list = new ArrayList<IMethod>();
		IMethod[] methods = type.getMethods();
		for(int i=0;i<methods.length;i++){
			if(!methods[i].isConstructor() && !methods[i].isMainMethod() && Flags.isPublic(methods[i].getFlags())){
				list.add(methods[i]);
			}
		}
		// search super class
		ITypeHierarchy hierarchy = type.newSupertypeHierarchy(null);
		extractMethods(hierarchy.getAllSuperclasses(type), list);
		extractMethods(hierarchy.getSuperInterfaces(type), list);
		
		if(type.isInterface()){
			extractMethods(new IType[]{
					type.getJavaProject().findType("java.lang.Object")}, list);
		}
		return (IMethod[])list.toArray(new IMethod[list.size()]);
	}
	
	private static void extractMethods(IType[] types, List<IMethod> methods) throws JavaModelException {
		for(int i=0;i<types.length;i++){
			IMethod[] superMethods = types[i].getMethods();
			for(int j=0;j<superMethods.length;j++){
				boolean flag = true;
				if(!superMethods[j].isConstructor() && !superMethods[j].isMainMethod() && Flags.isPublic(superMethods[j].getFlags())){
					for(int k=0;k<methods.size();k++){
						IMethod method = (IMethod)methods.get(k);
						if(equalsMethods(method, superMethods[j])){
							flag = false;
							break;
						}
					}
					if(flag){
						methods.add(superMethods[j]);
					}
				}
			}
		}
	}
	
	/**
	 * Tests whether given methods are same.
	 * 
	 * @param method1 the <code>IMethod</code>
	 * @param method2 the <code>IMethod</code>
	 * @return <code>true</code> if given methods are same: <code>false</code> otherwise 
	 */
	private static boolean equalsMethods(IMethod method1, IMethod method2){
		if(method1.getElementName().equals(method2.getElementName())){
			String[] params1 = method1.getParameterTypes();
			String[] params2 = method2.getParameterTypes();
			if(params1.length==params2.length){
				for(int i=0;i<params1.length;i++){
					if(!params1[i].equals(params2[i])){
						return false;
					}
				}
				return true;
			}
		}
		return false;
	}
	
}
