/*******************************************************************************
 * Copyright (c) 2007 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:
 *    Oracle - initial API and implementation
 *    
 ********************************************************************************/
package org.eclipse.jst.jsf.common.metadata.query;

import javax.xml.namespace.QName;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jst.jsf.common.JSFCommonPlugin;
import org.eclipse.jst.jsf.common.metadata.Entity;
import org.eclipse.jst.jsf.common.metadata.Model;
import org.eclipse.jst.jsf.common.metadata.Trait;
import org.eclipse.jst.jsf.common.metadata.internal.IMetaDataModelContext;
import org.eclipse.jst.jsf.common.metadata.internal.IMetaDataModelManager;
import org.eclipse.jst.jsf.common.metadata.internal.MetaDataModelManagerFactory;
import org.eclipse.jst.jsf.common.metadata.internal.ModelKeyDescriptor;
import org.eclipse.jst.jsf.common.metadata.internal.TaglibDomainMetaDataModelContextImpl;
import org.eclipse.jst.jsf.common.metadata.query.internal.HierarchicalSearchControl;
import org.eclipse.jst.jsf.common.metadata.query.internal.SimpleEntityQueryVisitorImpl;
import org.eclipse.jst.jsf.common.metadata.query.internal.SimpleTraitQueryVisitorImpl;


/**
 * Helper class with static methods to simplify querying of a metadata model. 
 * 
 * <p>Steps for use:
 * 	<br>1) Get the ITaglibDomainMetaDataModelContext using createMetaDataModelContext or createTagLibraryDomainMetaDataModelContext
 * 	<br>2) Use appropriate getXXX methods using the ITaglibDomainMetaDataModelContext.
 * <p><b>Provisional API - subject to change</b></p>
 * 
 * @deprecated - Helios <p> 
 * 			use ITaglibMetaDataQuery:<p>
 * 			<code>
 * 				IMetaDataDomainContext context 	= MetaDataQueryContextFactory.getInstance().createTaglibDomainModelContext(project);<br/>
 * 				ITaglibMetaDataQuery query 		= MetaDataQueryFactory.getInstance().createQuery(context);
 * 			</code> 
 * <p>
 * @see IResultSet
 * @see IEntityQueryVisitor
 * @see ITraitQueryVisitor
 * @see ITaglibDomainMetaDataModelContext
 * @see Model
 * @see Entity
 * @see Trait
 * 

 */			
public final class TaglibDomainMetaDataQueryHelper{
	/**
	 * Domain id for Tag library domain of metatdata  
	 */
	public static final String TAGLIB_DOMAIN = "TagLibraryDomain"; //need better place for this //$NON-NLS-1$
	
	/**
	 * private constructor
	 */
	private TaglibDomainMetaDataQueryHelper (){
		super();
	}
	
	/**
	 * Convenience method for creating {@link ITaglibDomainMetaDataModelContext}s for TAGLIB_DOMAIN
	 * @param project
	 * @param uri
	 * @return ITaglibDomainMetaDataModelContext
	 */
	public static ITaglibDomainMetaDataModelContext createMetaDataModelContext(IProject project, String uri){
		return new TaglibDomainMetaDataModelContextImpl(TAGLIB_DOMAIN, project, uri);
	}
	/**
	 * @param modelContext
	 * @return Model object for given context.   May return null if not located.
	 */
	public static Model getModel(final ITaglibDomainMetaDataModelContext modelContext) {
//		MetaDataModel model = getMDModel(modelContext);
//		//we may want to throw error that model is empty
//		if (model != null && !model.isEmpty()){			
//			return (Model)model.getRoot();
//		}
		return getMDModel(modelContext);
	}

	/**
	 * @param modelContext
	 * @param entityKey relative to root of the model
	 * @return the first entity match from the root of the model.   May return null.
	 */
	public static Entity getEntity(final ITaglibDomainMetaDataModelContext modelContext,
			final String entityKey) {
		IEntityQueryVisitor visitor = new SimpleEntityQueryVisitorImpl(new HierarchicalSearchControl(1, HierarchicalSearchControl.SCOPE_ALL_LEVELS));
		IResultSet/*<Entity>*/ rs = getEntities(modelContext,entityKey,  visitor);
		Entity e = null;
		try {
			if (! rs.getResults().isEmpty()){
				e = (Entity)rs.getResults().get(0);				
			}
			rs.close();
		} catch (MetaDataException ex) {
			JSFCommonPlugin.log(IStatus.ERROR, "Error in Helper.getEntity() - 1", ex); //$NON-NLS-1$
		}

		return e;
	}

	/**
	 * @param modelContext 
	 * @param entityKey relative to root of model 
	 * @param visitor 
	 * @return an IResultSet of entity objects
	 */
	public static IResultSet/*<Entity>*/ getEntities(final ITaglibDomainMetaDataModelContext modelContext,
				final String entityKey, final IEntityQueryVisitor visitor){
		Model model = getModel(modelContext);
		//we may want to throw error that model is empty
		return getEntities(model, entityKey, visitor);
		
	}

	/**
	 * @param entity
	 * @param traitKey
	 * @return a trait or null for the given entity and traitKey using a SimpleEntityQueryVisitorImpl 
	 */
	public static Trait getTrait(final Entity entity, final String traitKey){
		ITraitQueryVisitor visitor = new SimpleTraitQueryVisitorImpl();	
		Trait t= null;
		IResultSet/*<Trait>*/ rs = getTraits(entity, traitKey, visitor);
		try {
			if (! rs.getResults().isEmpty()){
				t = (Trait)rs.getResults().get(0);				
			}
			rs.close();
		} catch (MetaDataException ex) {
			JSFCommonPlugin.log(IStatus.ERROR, "Error in Helper.getTrait()", ex); //$NON-NLS-1$
		}

		return t;
	}

	/**
	 * @param entity
	 * @param traitKey
	 * @param traitQueryVisitor
	 * @return an IResultSet of trait objects using supplied traitQueryVisitor.  IResultSet should NOT be null.
	 */
	public static IResultSet/*<Trait>*/ getTraits(Entity entity, String traitKey,
			ITraitQueryVisitor traitQueryVisitor) { 
		IResultSet/*<Trait>*/ rs = traitQueryVisitor.findTraits(entity, traitKey);
		return rs;
	}

	/**
	 * @param initialEntityContext
	 * @param entityKey relative to initial passed entity
	 * @return the first entity located by key using SimpleEntityQueryVisitorImpl
	 */
	public static Entity getEntity(Entity initialEntityContext, String entityKey) {
		IEntityQueryVisitor visitor = new SimpleEntityQueryVisitorImpl(new HierarchicalSearchControl(1, HierarchicalSearchControl.SCOPE_ALL_LEVELS));
		Entity e= null;
		IResultSet/*<Entity>*/ rs = getEntities(initialEntityContext, entityKey, visitor);
		try {
			if (! rs.getResults().isEmpty()){
				e = (Entity)rs.getResults().get(0);				
			}
			rs.close();
		} catch (MetaDataException ex) {
			JSFCommonPlugin.log(IStatus.ERROR, "Error in Helper.getEntity() - 0", ex); //$NON-NLS-1$
		}		

		return e;		
	}

	/**
	 * @param initialEntityContext
	 * @param entityQuery relative to initial passed entity
	 * @param entityKeyQueryVisitor
	 * @return IResultSet of entities located by key using entityQueryVisitor.  IResultSet should NOT be null.
	 */
	public static IResultSet/*<Entity>*/ getEntities(Entity initialEntityContext, String entityQuery,
			IEntityQueryVisitor entityKeyQueryVisitor) {
				
		return entityKeyQueryVisitor.findEntities(initialEntityContext, entityQuery);	
	}

	
	/**
	 * Retrieve the MetaDataModel from the ModelManager for given key
	 * @param modelContext
	 * @return Model
	 */
	private static Model getMDModel(final ITaglibDomainMetaDataModelContext modelContext){
		final IMetaDataModelContext context = getContextAdapter(modelContext);		
		final IMetaDataModelManager mgr = MetaDataModelManagerFactory.getMetaDataModelManagerInstance(modelContext.getProject());
		if (mgr != null)
			return mgr.getModel(context);
		
//		MetaDataModelManager mgr = null;
//		if (modelContext.getProject() != null)
//			mgr = MetaDataModelManager.getInstance(modelContext.getProject());
//		else //temp(?)
//			mgr = MetaDataModelManager.getSharedInstance();	
//		
//		if (mgr != null)
//			return mgr.getModel(modelContext);
		
		return null;
	}

	private static IMetaDataModelContext getContextAdapter(
			final ITaglibDomainMetaDataModelContext modelContext) {		
		return new IMetaDataModelContext() {
			
			public Object getAdapter(Class adapter) {	
				if (adapter == IProject.class)
					return getProject();
				else if (adapter == ModelKeyDescriptor.class)
					return new ModelKeyDescriptor(modelContext.getProject(), modelContext.getDomainID(), modelContext.getURI());
				return null;
			}
			
			public String getDomainId() {				
				return modelContext.getDomainID();
			}
			
			public IProject getProject() {
				return modelContext.getProject();
			}
			
			public String getModelIdentifier() {
				//doing below for "fixing" the jsp11 uri
				return ((ModelKeyDescriptor)getAdapter(ModelKeyDescriptor.class)).getUri();
			}
		};
	}

	/**
	 * @param modelContext
	 * @param entityKey
	 * @param traitKey
	 * @return first trait found for entity and trait key starting from root of the model using SimpleMetaDataQueryImpl
	 */
	public static Trait getTrait(final ITaglibDomainMetaDataModelContext modelContext,
			final String entityKey, final String traitKey) { 
		Entity entity = getEntity(modelContext, entityKey);
		Trait t = null;
		if (entity != null){			
			t = getTrait(entity, traitKey);
		}
		return t;
	}	
	
	/**
	 * @param tagEntity
	 * @return QName for tag entity
	 */
	public static QName getQNameForTagEntity(Entity tagEntity) {
		Assert.isTrue(tagEntity != null);
		return new QName(tagEntity.getModel().getCurrentModelContext().getUri(), tagEntity.getId());
	}
}
