/*******************************************************************************
 * Copyright (c) 2006 Oracle Corporation.
 * 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:
 *    Gerry Kessler/Oracle - initial API and implementation
 *    
 ********************************************************************************/
package org.eclipse.jst.jsf.taglibprocessing.attributevalues;

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

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.ICompilationUnit;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
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.search.IJavaSearchConstants;
import org.eclipse.jdt.core.search.IJavaSearchScope;
import org.eclipse.jdt.core.search.SearchEngine;
import org.eclipse.jdt.core.search.SearchMatch;
import org.eclipse.jdt.core.search.SearchParticipant;
import org.eclipse.jdt.core.search.SearchPattern;
import org.eclipse.jdt.core.search.SearchRequestor;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IStructuredDocumentContextResolverFactory;
import org.eclipse.jst.jsf.context.resolver.structureddocument.IWorkspaceContextResolver;
import org.eclipse.jst.jsf.metadataprocessors.features.IPossibleValues;
import org.eclipse.jst.jsf.metadataprocessors.features.IValidValues;
import org.eclipse.jst.jsf.metadataprocessors.features.PossibleValue;
import org.eclipse.jst.jsf.metadataprocessors.features.ValidationMessage;

/**
 * Provides possible values and validates attribute values that should be fully qualified Java types.
 * A type can be verified against muliple "valid-interfaces" and/or a "valid-superclass" from meta-data.
 * Code checks to ensure the class can be instantiated (i.e. not abstract, anonymous or inner class)
 * Search is scoped to within the current project only. 
 * 
 * (Until https://bugs.eclipse.org/bugs/show_bug.cgi?id=142044 is fixed, only the first found will be used)
 * 
 * <p><b>Provisional API - subject to change</b></p>
 * @author Gerry Kessler - Oracle
 *
 */
public class JavaClassType extends ObjectType implements IPossibleValues, IValidValues{
	/**
	 * Trait name for valid interfaces
	 */
	public static final String POSSIBLE_VALUES_INTERFACES_PROP_NAME = "valid-interfaces"; //$NON-NLS-1$
	/**
	 * Trait name for valid superclass
	 */
	public static final String POSSIBLE_VALUES_SUPERCLASS_PROP_NAME = "valid-superclass"; //$NON-NLS-1$
	
	private List validationMsgs;
	
	/* (non-Javadoc)
	 * @see org.eclipse.jst.jsf.metadataprocessors.features.IPossibleValues#getPossibleValues()
	 */
	public List getPossibleValues() {
		List results = getTypes();
		if (results != null && !results.isEmpty()){
			
			Set vals = new HashSet(results.size());
			Set checkedTypes = new HashSet();
			for (Iterator it = results.iterator();it.hasNext();){
				SearchMatch match = (SearchMatch)it.next();
				IType res = (IType)match.getElement();
				addValidSubClasses(res, vals, checkedTypes);					
			}
			return createPossibleValues(vals);
		}						
		return new ArrayList(0);
	}
	
	private List createPossibleValues(Set vals) {
		List list = new ArrayList(vals.size());
		Iterator it = vals.iterator();
		while(it.hasNext()){
			IJavaElement elem = (IJavaElement)it.next();
			list.add(createPossibleValue(elem));
		}
		return list;
	}

	private void addValidSubClasses(IType res, Set vals, Set checkedTypes) {

		try {
			//check to see if we have already checked the hiearchy
			if (checkedTypes.contains(res))
				return;
						
			//should we add itself?
			if (isInnerOrAnonymousClass(res))
				return;
			if (!isAbstractClass(res))
				vals.add(res);  //since it is a set, dupes will not be added
			

			ITypeHierarchy hierarchy = res.newTypeHierarchy(getJavaProject(), null);			
			IType[] subclasses = hierarchy.getSubclasses(res);
			checkedTypes.add(res);
			for (int i=0;i<subclasses.length;i++){
				addValidSubClasses(subclasses[i], vals, checkedTypes);
			}
		} catch (JavaModelException e) {
			//ignore
		}
	}

	private IWorkspaceContextResolver getWorkspaceContextResolver(){
		if (getStructuredDocumentContext() == null)
			return null;
		
		 return IStructuredDocumentContextResolverFactory.INSTANCE.getWorkspaceContextResolver(getStructuredDocumentContext());
	}
	
	private List getTypes(){
		IJavaProject jp = getJavaProject();
		if (jp == null)
			return null;
		
		List elems = new ArrayList();
		elems.addAll(getInterfaces(jp));
		IType sc = getSuperClass(jp);
		if (sc != null)
			elems.add(sc);
			
		if (elems.size() > 0){				
			SearchRequestor requestor = new Searcher();
			SearchEngine engine = new SearchEngine();
			
			IJavaSearchScope scope = SearchEngine.createJavaSearchScope(new IJavaElement[]{jp}, IJavaSearchScope.SOURCES | IJavaSearchScope.APPLICATION_LIBRARIES);
			SearchPattern combined = SearchPattern.createPattern((IJavaElement)elems.get(0), IJavaSearchConstants.IMPLEMENTORS, 0);

//			 Until this bug is fixed, stub it out...  only the first interface/superclass will be used.
//							https://bugs.eclipse.org/bugs/show_bug.cgi?id=142044
//							for(int i=1;i<elems.size();i++){
//								final SearchPattern other = SearchPattern.createPattern((IJavaElement)elems.get(i), IJavaSearchConstants.IMPLEMENTORS, 0);
//								combined = SearchPattern.createAndPattern(combined, other);
//							}
			
			try {
				engine.search(combined, new SearchParticipant[] {SearchEngine.getDefaultSearchParticipant()}, scope, requestor, null);
				
			} catch (CoreException e) {
				//ignore
			}

			return ((Searcher)requestor).getResults();	
		}

		return new ArrayList(0);
	}
	
	private IJavaProject getJavaProject() {
		IWorkspaceContextResolver resolver = getWorkspaceContextResolver();
		if (resolver != null){
			IProject proj = resolver.getProject();
			if (proj != null)
				return JavaCore.create(proj);
		}
		return null;
	}

	private List getInterfaces(IJavaProject jp) {
		List ret = new ArrayList();
		List propVals = getInterfaceNames();		
		
		for (Iterator it = propVals.iterator();it.hasNext();){
			String propVal = (String)it.next();
			IType interfase = null;
			try {
				interfase = findType(jp, propVal);
				if (interfase != null){
					ret.add(interfase);
				}
			} catch (JavaModelException e) {
                // suppress and fall-through to return empty list
			}

		}
		return ret;
	}
	
	private IType getSuperClass(IJavaProject jp){
		IType superclass = null;
		try {
			String sc = getSuperClassName();
			if (sc != null && !sc.trim().equals("")){ //$NON-NLS-1$
				superclass = findType(jp, sc );
				if (superclass != null){
					return superclass;
				}
			}
		} catch (JavaModelException e) {
			//ignore
		}
		return null;
	}
	
	private PossibleValue createPossibleValue(IJavaElement val) {
		return new PossibleValue(((IType)val).getFullyQualifiedName());		
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jst.jsf.metadataprocessors.features.IValidValues#getValidationMessages()
	 */
	public List getValidationMessages() {
		if (validationMsgs == null){
			validationMsgs = new ArrayList();			
		}
		return validationMsgs;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.jst.jsf.metadataprocessors.features.IValidValues#isValidValue(java.lang.String)
	 */
	public boolean isValidValue(String value) {
		if (value == null || value.trim().equals("")){ //$NON-NLS-1$
			getValidationMessages().add(new ValidationMessage(Messages.JavaClassType_invalid_type));
			return false;
		}
		IJavaProject jp = getJavaProject();
		if (jp == null)
			return false;
		
		//first verify that the value specified is a resolvable type
		IType type = getTypeForValue(jp, value);
		if (type != null){			
			//ensure that it is not abstract or anonymous
			if (!isInnerOrAnonymousClass(type) && !isAbstractClass(type)){
				//now verify that it meets the criteria
				List results = getTypes();
				if (!results.isEmpty()){					
					for (Iterator it = results.iterator();it.hasNext();){
						SearchMatch match = (SearchMatch)it.next();
						IType res = (IType)match.getElement();
						if (!isInnerOrAnonymousClass(res) ){
							//if this is the class, then optimize to reduce expense of creating hierarchy
							if (!isAbstractClass(type) && (res.getFullyQualifiedName().equals(value)) )
								return true;
							//check to see if value is in hierarchy
							try {
								ITypeHierarchy hierarchy = res.newTypeHierarchy(jp, null);
								if (hierarchy.contains(type))
									return true;
							} catch (JavaModelException e) {
								//ignore
							}
						}
					}
				}
			}
		}
		addNewValidationMessage(Messages.JavaClassType_not_found);
		return false;
	}
	
	private IType getTypeForValue(IJavaProject jp, String value) {
		try {
			return findType(jp, value);
		} catch (JavaModelException e) {
            // suppress and fall through to return null
		}
		return null;
	}

	/**
	 * @return String value of {@link #POSSIBLE_VALUES_SUPERCLASS_PROP_NAME}
	 */
	protected String getSuperClassName(){
		return getTraitValueAsString(POSSIBLE_VALUES_SUPERCLASS_PROP_NAME);
//		return CMAnnotationHelper.getCMAttributePropertyValue(getMetaDataContext().getBundleId(), getMetaDataContext().getUri(),
//				getMetaDataContext().getElementName(), getMetaDataContext().getAttributeName(),
//				POSSIBLE_VALUES_SUPERCLASS_PROP_NAME);

	}
	
	/**
	 * @return List of values from {@link #POSSIBLE_VALUES_INTERFACES_PROP_NAME}
	 */
	protected List getInterfaceNames(){
		return getTraitValueAsListOfStrings(POSSIBLE_VALUES_INTERFACES_PROP_NAME);
		
//		return CMAnnotationHelper.getCMAttributePropertyValues(getMetaDataContext().getBundleId(), getMetaDataContext().getUri(),
//				getMetaDataContext().getElementName(), getMetaDataContext().getAttributeName(),
//				POSSIBLE_VALUES_INTERFACES_PROP_NAME);

	}

	/**
	 * Create a {@link ValidationMessage} from metadata or use default message
	 * and add it to the collection of validation messages
	 * @param defaultMsg
	 */
	protected void addNewValidationMessage(String defaultMsg) {
		//TODO: need to refactor below as this as also in Enumeration
		String msg = getCMValidationMessage();
		if (msg == null || msg.equals("")) //$NON-NLS-1$
			msg = defaultMsg;
		
		String code = getValidationCode();
		int severity = getValidationSeverity();
		ValidationMessage val = new ValidationMessage(msg, code, severity);
		getValidationMessages().add(val);
	}
	
	
	/**
	 * @return validation message from meta-data using {@link IValidValues}.VALID_VALUES_MESSAGE_PROP_NAME trait.   Can be null.
	 */
	protected String getCMValidationMessage() {
		return getTraitValueAsString(IValidValues.VALID_VALUES_MESSAGE_PROP_NAME);			
	}
	
	/**
	 * @return validation severity as int from meta-data using {@link IValidValues}.VALID_VALUES_SEVERITY_PROP_NAME trait.   IStatus.WARNING is default.
	 */
	protected int getValidationSeverity() {
		String val = getTraitValueAsString(IValidValues.VALID_VALUES_SEVERITY_PROP_NAME);		
		if (val == null)
			return IStatus.WARNING;
		
		int severity = Integer.valueOf(val).intValue();
		return severity;
	}

	/**
	 * @return validation code as String from meta-data.   Can be null.
	 */
	protected String getValidationCode() {
		return getTraitValueAsString(IValidValues.VALID_VALUES_CODE_PROP_NAME);		
	}
	
	private boolean isInnerOrAnonymousClass(IType res) {
		try {
			if (res.isClass() && (res.isAnonymous() || 
									(Flags.isPrivate(res.getFlags())) || 
									res.getFullyQualifiedName().indexOf("$") > 0)) //must be better way to discover if it is an inner class //$NON-NLS-1$
				return true;
		} catch (JavaModelException e) {
			//ignore
		}
		return false;
	}


	private boolean isAbstractClass(IType res) {	
		try {
			if (res.isClass() && Flags.isAbstract(res.getFlags()))
				return true;
		} catch (JavaModelException e) {
			//ignore
		}
		return false;
	}
	
	private class Searcher extends SearchRequestor{
		private List results = new ArrayList();
		public void acceptSearchMatch(SearchMatch match) throws CoreException {
			results.add(match);
		}
		
		/**
		 * @return list of serach results
		 */
		public List getResults(){
			return results;
		}
	}
	
/////////////////  ///////////////////////////////////////////////////////////////////////
//remainder of this class copied from org.eclipse.jdt.internal.corext.util.JavaCoreUtil //
//TODO: find public version of this functionality										//
//////////////////////////////////////////////////////////////////////////////////////////
	private IType findType(IJavaProject jproject, String fullyQualifiedName) throws JavaModelException {
		//workaround for bug 22883
		IType type= jproject.findType(fullyQualifiedName);
		if (type != null)
			return type;

		IPackageFragmentRoot[] roots= jproject.getPackageFragmentRoots();
		for (int i= 0; i < roots.length; i++) {
			IPackageFragmentRoot root= roots[i];
			type= findType(root, fullyQualifiedName);
			if (type != null && type.exists())
				return type;
		}	
		return null;
	}
	
	private IType findType(IPackageFragmentRoot root, String fullyQualifiedName) throws JavaModelException{
		IJavaElement[] children= root.getChildren();
		for (int i= 0; i < children.length; i++) {
			IJavaElement element= children[i];
			if (element.getElementType() == IJavaElement.PACKAGE_FRAGMENT){
				IPackageFragment pack= (IPackageFragment)element;
				if (! fullyQualifiedName.startsWith(pack.getElementName()))
					continue;
				IType type= findType(pack, fullyQualifiedName);
				if (type != null && type.exists())
					return type;
			}
		}		
		return null;
	}
	
	private IType findType(IPackageFragment pack, String fullyQualifiedName) throws JavaModelException{
		ICompilationUnit[] cus= pack.getCompilationUnits();
		for (int i= 0; i < cus.length; i++) {
			ICompilationUnit unit= cus[i];
			IType type= findType(unit, fullyQualifiedName);
			if (type != null && type.exists())
				return type;
		}
		return null;
	}
	
	private IType findType(ICompilationUnit cu, String fullyQualifiedName) throws JavaModelException{
		IType[] types= cu.getAllTypes();
		for (int i= 0; i < types.length; i++) {
			IType type= types[i];
			if (getFullyQualifiedName(type).equals(fullyQualifiedName))
				return type;
		}
		return null;
	}
	
	private String getFullyQualifiedName(IType type) {
		try {
			if (type.isBinary() && !type.isAnonymous()) {
				IType declaringType= type.getDeclaringType();
				if (declaringType != null) {
					return getFullyQualifiedName(declaringType) + '.' + type.getElementName();
				}
			}
		} catch (JavaModelException e) {
			// ignore
		}		
		return type.getFullyQualifiedName('.');
	}
////////////////////////////////////////////////////////////////////////
}
