/*******************************************************************************
 * Copyright (c) 2005, 2012 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.jdt.debug.tests.refactoring;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.debug.internal.core.IInternalDebugCoreConstants;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IField;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMember;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.core.Signature;
import org.eclipse.jdt.internal.core.SourceMethod;
import org.eclipse.jdt.internal.core.SourceType;

/**
 * Contains methods to find an IMember within a given path subdivided by the '$' character.
 * Syntax:
 * Type$InnerType$MethodNameAndSignature$AnonymousTypeDeclarationNumber$FieldName
 * eg:<code>
 * public class Foo{
 * 		class Inner
 * 		{
 * 			public void aMethod()
 * 			{
 * 				Object anon = new Object(){
 * 					int anIntField;
 * 					String anonTypeMethod() {return "an Example";}
 * 				}
 * 			}
 * 		}
 * }</code>
 * Syntax to get anIntField would be: Foo$Inner$aMethod()V$1$anIntField
 * Syntax to get the anonymous toString would be: Foo$Inner$aMethod()V$1$anonTypeMethod()QString
 * In the case of local types, the listed syntax should be Count and then Name, like: CountName
 * eg:<code>1MyType</code>
 */
public class MemberParser{

	/**
	 * @param typeQualifiedName
	 * @return
	 */
	private static ArrayList<String> createTypeList(String typeQualifiedName) {
		String newname = typeQualifiedName;
		newname = newname.replace('$','.');//ensure proper format was used.
		String parsed[] = newname.split("\\."); //$NON-NLS-1$
		//make list of types to find
		ArrayList<String> typeList = new ArrayList<String>();
		for (int splitNum = 0; splitNum < parsed.length; splitNum++) {
			typeList.add(parsed[splitNum]);
		}
		return typeList;
	}
	/**
	 * @param fragments the scope of which you wish to return compilation units
	 * @return a handle to all compilation units contained by the given fragments
	 * @throws JavaModelException
	 */
	private static ICompilationUnit[] getAllCompilationUnits(IPackageFragment[] fragments) throws JavaModelException {
		if(fragments == null)
			return null;
		final Set<ICompilationUnit> results = new HashSet<ICompilationUnit>();
		for (int fragmentNum = 0; fragmentNum < fragments.length; fragmentNum++) {
			if(fragments[fragmentNum].containsJavaResources()){
				ICompilationUnit cunits[] = fragments[fragmentNum].getCompilationUnits();
				for (int cunitNum = 0; cunitNum < cunits.length; cunitNum++) {
					results.add(cunits[cunitNum]);
				}
			}
		}
		if(results.isEmpty())
			return null;
		return results.toArray(new ICompilationUnit[results.size()]);
	}

	/**
	 * @param projects the scope of which you wish to return compilation units
	 * @return a handle to all compilation units contained by the given projects
	 * @throws JavaModelException
	 */
	private static ICompilationUnit[] getAllCompilationUnits(IProject[] projects)  throws JavaModelException{
		return getAllCompilationUnits(getAllPackageFragments(projects));
	}

	private static ICompilationUnit[] getAllCompilationUnits(String packageName, IProject[] projects)throws JavaModelException {
		return getAllCompilationUnits(getAllPackageFragments(packageName, projects));
	}

	/**
	 * @param types
	 * @return an array of all declared methods for the given types
	 * @throws JavaModelException
	 */
	private static IMethod[] getAllMethods(IType[] types) throws JavaModelException{
		if(types==null)
			return null;

		final Set<IMethod> results = new HashSet<IMethod>();
		for (int typeNum = 0; typeNum < types.length; typeNum++) {
			IMethod[] methods = types[typeNum].getMethods();
			for (int methodNum = 0; methodNum < methods.length; methodNum++) {
				results.add(methods[methodNum]);
			}
		}
		if(results.isEmpty())
			return null;
		return results.toArray(new SourceMethod[results.size()]);
	}

	/**
	 * @param projects the scope of the return
	 * @return all package fragments in the scope
	 * @throws JavaModelException
	 */
	private static IPackageFragment[] getAllPackageFragments(IProject[] projects) throws JavaModelException {
		final Set<IPackageFragment> results = new HashSet<IPackageFragment>();
		for (int projectNum = 0; projectNum < projects.length; projectNum++) {
			IJavaProject javaProj = JavaCore.create(projects[projectNum]);
			if(javaProj!= null && javaProj.exists() && javaProj.hasChildren()){
				IPackageFragment fragments[] = javaProj.getPackageFragments();
				for (int fragmentNum = 0; fragmentNum < fragments.length; fragmentNum++) {
					results.add(fragments[fragmentNum]);
				}
			}
		}
		if(results.isEmpty())
			return null;
		return results.toArray(new IPackageFragment[results.size()]);
	}
	/**
	 * @return all projects in the workspace
	 */
	private static IProject[] getAllProjects(){
		return ResourcesPlugin.getWorkspace().getRoot().getProjects();
	}

	/**
	 * @param cunits the scope of the search
	 * @return all types within the scope
	 * @throws JavaModelException
	 */
	private static IType[] getAllTypes(ICompilationUnit[] cunits) throws JavaModelException {
		if(cunits == null)
			return null;

		final Set<IType> results = new HashSet<IType>();
		for (int cunitNum = 0; cunitNum < cunits.length; cunitNum++) {
			IType types[] = cunits[cunitNum].getTypes(); //get all topLevel types
			for (int typeNum = 0; typeNum < types.length; typeNum++) {
				results.add(types[typeNum]);
			}
		}
		if(results.isEmpty())
			return null;
		return results.toArray(new IType[results.size()]);
	}

	/**
	 * @param methods the scope of the search
	 * @return an array of all types declared within the given methods.
	 * @throws JavaModelException
	 */
	private static IType[] getAllTypes(IMethod[] methods) throws JavaModelException {
		if(methods==null)
			return null;
		final Set<IJavaElement> results = new HashSet<IJavaElement>();
		for (int methodNum = 0; methodNum < methods.length; methodNum++) {
			IJavaElement[] children = methods[methodNum].getChildren();
			for (int childNum = 0; childNum < children.length; childNum++) {
				if(children[childNum] instanceof IType)
					results.add(children[childNum]);
			}
		}
		if(results.isEmpty())
			return null;
		return results.toArray(new SourceType[results.size()]);
	}

	/**Will search within the given type and all of it's children - including methods
	 * and anonymous types for other types.
	 * @param types the scope of the search
	 * @return all types within the given scope
	 * @throws JavaModelException
	 */
	public static IType[] getAllTypes(IType[] types) throws JavaModelException{
		if(types == null)
			return null;
		IType[] newtypes = types;
		final Set<IType> results = new HashSet<IType>();
		//get all the obvious type declarations
		for (int mainTypeNum = 0; mainTypeNum < newtypes.length; mainTypeNum++) {
			IType declaredTypes[] = newtypes[mainTypeNum].getTypes();
			for (int declaredTypeNum = 0; declaredTypeNum < declaredTypes.length; declaredTypeNum++) {
				results.add(declaredTypes[declaredTypeNum]);
			}
			//get all the type's method's type declarations
			newtypes = getAllTypes(getAllMethods(newtypes));
			for (int methodTypes = 0; methodTypes < newtypes.length; methodTypes++) {
				results.add(newtypes[methodTypes]);
			}
		}
		if(results.isEmpty())
			return null;
		//else
		return results.toArray(new SourceType[results.size()]);//possibly change to new IType
	}


	/**
	 * Returns the Java project with the given name.
	 *
	 * @param name project name
	 * @return the Java project with the given name
	 */
	static protected IJavaProject getJavaProject() {
		IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject();
		return JavaCore.create(project);
	}

	/**
	 * @param packageName name of the package
	 * @param projects where to search
	 * @return the 1st instance of the given packageName
	 * @throws JavaModelException
	 */
	private static IPackageFragment[] getAllPackageFragments(String packageName, IProject[] projects) throws JavaModelException{
		final Set<IPackageFragment> results = new HashSet<IPackageFragment>();
		for (int projectNum = 0; projectNum < projects.length; projectNum++) {
			IJavaProject javaProj = JavaCore.create(projects[projectNum]);
			if(javaProj!= null && javaProj.exists() && javaProj.hasChildren()){
				IPackageFragment fragments[] = javaProj.getPackageFragments();
				for (int fragmentNum = 0; fragmentNum < fragments.length; fragmentNum++) {
					if(fragments[fragmentNum].getElementName().equalsIgnoreCase(packageName))
						results.add(fragments[fragmentNum]);
				}
			}
		}
		if(results.isEmpty())
			return null;
		//else
		return results.toArray(new IPackageFragment[results.size()]);
	}

	private static IProject getProject(String projectName){
		return ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
	}

	private static IType getType(ArrayList<String> typeList, ICompilationUnit[] cunits) throws JavaModelException{
		IType[] types = getAllTypes(cunits);
		//if 1st letter is a number, it's anonymous
		boolean targetIsAnonymous = Character.isDigit(typeList.get(0).toString().charAt(0));
		boolean targetFound=false;
		char separator = '.';
		while (true) {//search all types for desired target - will return internally.
			//check all the types we have
			int typeNum=0;
			while(typeNum < types.length) {//search current list of types
				if(targetIsAnonymous){//must ensure format is same for both.
					String nameOfCurrentType = types[typeNum].getTypeQualifiedName(separator);
					nameOfCurrentType = nameOfCurrentType.substring(nameOfCurrentType.lastIndexOf(separator)+1);
					targetFound = nameOfCurrentType.equalsIgnoreCase(typeList.get(0).toString());
				}else{
					targetFound = types[typeNum].getElementName().equalsIgnoreCase(typeList.get(0).toString());
				}
				if(targetFound){//yay!
					typeList.remove(0);
					if(typeList.isEmpty()){
						return types[typeNum];//we're at our destination
					}
					//else, get all this type's subtypes
					types = getAllTypes(new IType[]{types[typeNum]});//get next level
//					check format of this new type
					targetIsAnonymous = Character.isDigit(typeList.get(0).toString().charAt(0));
					typeNum = 0;//start again.
				}
				else
					typeNum++;//check the next type
			}

			//else, it is not in the top-level types - check in methods
			types = getAllTypes(getAllMethods(types));
			if(types==null)
				return null;//couldn't find it.
		}//end while
	}

	/**
	 * Will search the workspace and return the requested type. The more information given,
	 * the faster the search
	 * @param typeName the name of the type, with or without qualifiers - it cannot be null
	 * 		e.g. "aType.innerType.1.typeInAnonymousType" or even just "typeInAnonymousType"
	 * 		or "innerType.1.typeInAnonymousType".
	 * @param packageName the elemental name of the package containing the given type - may be null
	 * @param projectName the elemental name of the project containing the given type - may be null
	 * @return the IType handle to the requested type
	 * @throws JavaModelException
	 */
	public static IType getType(String typeName, String packageName, String projectName) throws JavaModelException{
		if(typeName == null)
			return null;
		//make list of types to find, in order
		ArrayList<String> typeList = createTypeList(typeName);
		//get the proper project(s)
		IProject[] projects=null;
		if(projectName!=null && projectName.length()>0){
			projects = new IProject[] {getProject(projectName)};
		}
		else{
			projects = getAllProjects();
		}

		//get the Comp.units for those projects
		ICompilationUnit cunits[] = null;
		if(packageName!=null && packageName.length()>0){
			cunits = getAllCompilationUnits(packageName, projects);
		}
		else{
			cunits = getAllCompilationUnits(projects);
		}

		return getType(typeList, cunits);
	}


	/**
	 * @param cu the CompilationUnit containing the toplevel Type
	 * @param target - the IMember target, listed in full Syntax, as noted in MemberParser
	 * eg: EnclosingType$InnerType
	 * @return the Lowest level inner type specified in input
	 */
	public IMember getDeepest(ICompilationUnit cu, String target)
	{
		for(int i=0;i<target.length();i++)
		{
			if(target.charAt(i)=='$')
			{//EnclosingType$InnerType$MoreInner
				String tail = target.substring(i+1);
				IType enclosure = cu.getType(target.substring(0, i));
				if(enclosure.exists())
					return getDeepest(enclosure,tail);
			}
		}
		//has no inner type
		return cu.getType(target);

	}

	/**
	 * Helper method for getLowestType (ICompilationUnit cu, String input)
	 * @param top name of enclosing Type
	 * @param tail the typename, possibly including inner type,
	 * separated by $.
	 * eg: EnclosingType$InnerType
	 * @return the designated type, or null if type not found.
	 */
	protected IMember getDeepest(IMember top, String tail) {
		String newtail = tail;
		if(newtail==null || newtail.length()==0 )
			return top;

		if(!top.exists())
			return null;

		//check if there are more nested elements
		String head=null;
		for(int i=0;i<newtail.length();i++)
		{
			if(newtail.charAt(i)=='$')//nested Item?
			{//Enclosing$Inner$MoreInner
				head = newtail.substring(0,i);
				newtail = newtail.substring(i+1);
				break;//found next item
			}
		}
		if(head==null)//we are at last item to parse
		{//swap Members
			head = newtail;
			newtail = null;
		}

		if(top instanceof IType)
			return getNextFromType(top, head, newtail);
		else
			if(top instanceof IMethod)
				return getNextFromMethod(top, head, newtail);
			else
				if(top instanceof IField)
					return getNextFromField(top, head, newtail);
		//else there is a problem!
		return getDeepest(top,newtail);
	}

	/**
	 * @param head the string to parse for a name
	 * @return the name in the type, given in the format "Occurance#Type"
	 * e.g. head = "1Type";
	 */
	protected String getLocalTypeName(String head) {
		for(int i=0;i<head.length();i++)
		{
			if(!Character.isDigit(head.charAt(i)))
			{
				return head.substring(i);
			}

		}
		return IInternalDebugCoreConstants.EMPTY_STRING;//entire thing is a number
	}

	/**
	 * @param head the string to parse for an occurrence
	 * @return the name in the type, given in the format "Occurance#Type"
	 * e.g. head = "1Type";
	 */
	protected int getLocalTypeOccurrence(String head) {
		for(int i=0;i<head.length();i++)
		{
			if(!Character.isDigit(head.charAt(i)))
				return Integer.parseInt(head.substring(0, i));
		}
		return Integer.parseInt(head);//entire thing is a number
	}

	/**
	 * @param head name of method w/ signature at the end
	 * @return simply the name of the given method, using format:
	 * methodNameSignature.
	 * e.g.  head = "someMethod()V"
	 */
	protected String getName(String head) {
		for(int i=0;i<head.length();i++)
		{
			if(head.charAt(i)=='(')//nested Item?
				return head.substring(0,i);
		}
		return null;
	}

	/**
	 * @param top the field in which to search
	 * @param head the next member to find
	 * @param tail the remaining members to find
	 * @return the next member down contained by the given Field
	 */
	protected IMember getNextFromField(IMember top, String head, String tail) {
		IField current = (IField)top;

		IType type = current.getType(getLocalTypeName(head),getLocalTypeOccurrence(head));
		if(type.exists())
			return getDeepest(type,tail);
		//else
		return null;//something failed.
	}

	/**
	 * @param top the member in which to search
	 * @param head the next member to find
	 * @param tail the remaining members to find
	 * @return the next member down contained by the given Method
	 */
	protected IMember getNextFromMethod(IMember top, String head, String tail) {
		//must be a local or anonymous type
		IMethod current = (IMethod)top;

		//is next part a Type?
		IType type = current.getType(getLocalTypeName(head), getLocalTypeOccurrence(head));
		if(type.exists())
			return getDeepest(type,tail);
		//else
		return null;
	}

	/**
	 * @param top the member in which to search
	 * @param head the next member to find
	 * @param tail the remaining members to find
	 * @return the next member down contained by the given Type
	 */
	protected IMember getNextFromType(IMember top, String head, String tail) {
		IType current = (IType)top;

		//is next part a Type?
		IMember next = current.getType(head);
		if(next.exists())
			return getDeepest(next,tail);
		//else, is next part a Field?
		next = current.getField(head);
		if(next.exists())
			return getDeepest(next,tail);
		//else, is next part a Method?
		next = current.getMethod(getName(head),getSignature(head));
		if(next.exists())
			return getDeepest(next,tail);
		//else
		return null;//something failed.
	}

	/**
	 * @param head name of method w/ signature at the end
	 * @return simply the ParameterTypeSignature, using format:
	 * methodNameSignature.
	 * e.g.  head = "someMethod()V"
	 */
	protected String[] getSignature(String head) {
		for(int i=0;i<head.length();i++)
		{
			if(head.charAt(i)=='(')//nested Item?
				return Signature.getParameterTypes(head.substring(i));
		}
		return null;
	}
}
