/*******************************************************************************
 * 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.MetaDataModel;
import org.eclipse.jst.jsf.common.metadata.internal.TaglibDomainMetaDataModelContextImpl;
import org.eclipse.jst.jsf.common.metadata.internal.MetaDataModelManager;
import org.eclipse.jst.jsf.common.metadata.query.internal.SimpleEntityQueryVisitorImpl;
import org.eclipse.jst.jsf.common.metadata.query.internal.SimpleTraitQueryVisitorImpl;
import org.eclipse.jst.jsf.common.metadata.query.internal.HierarchicalSearchControl;


/**
 * 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>
 * @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 null;
	}

	/**
	 * @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 MetaDataModel
	 */
	private static MetaDataModel getMDModel(final ITaglibDomainMetaDataModelContext modelContext){
		MetaDataModelManager mgr = null;
		if (modelContext.getProject() != null)
			mgr = MetaDataModelManager.getInstance(modelContext.getProject());
		else //temp(?)
			mgr = MetaDataModelManager.getSharedInstance();	

		return mgr.getModel(modelContext);
	}

	/**
	 * @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());
	}
}
