/*******************************************************************************
 * 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.metadataprocessors.internal;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.InvalidRegistryObjectException;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jst.jsf.core.internal.JSFCorePlugin;
import org.eclipse.jst.jsf.metadataprocessors.IType;

/**
 * Registry of <code>AbstractMetaDataEnabledType</code>s loaded from 
 * the <code>MetaDataEnabledFeatures</code> extension point
 * 
 * A map of features keyed by type id
 *
 */
public class MetaDataEnabledFeatureRegistry{
	private static final String EXTPTID = "MetaDataEnabledFeatures";
	private Map<String, List<IMetaDataEnabledFeatureExtension>> featuresMap;
	private Map<String, Class> typeCacheMap;
	private static MetaDataEnabledFeatureRegistry INSTANCE;
	
	/**
	 * @return the singleton instance of the MetaDataEnabledFeatureRegistry
	 */
	public static synchronized MetaDataEnabledFeatureRegistry getInstance(){
		if (INSTANCE == null){
			INSTANCE = new MetaDataEnabledFeatureRegistry();	
		}
		return INSTANCE;
	}
	
	private MetaDataEnabledFeatureRegistry(){
		featuresMap = new HashMap<String, List<IMetaDataEnabledFeatureExtension>>();
		typeCacheMap = new HashMap<String, Class>();
		readRegistry();		
	}
	
	/**
	 * Reads the MetaDataEnabledFeatures extensions into a registry
	 */
	protected void readRegistry() {
		try {
			IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(JSFCorePlugin.PLUGIN_ID, EXTPTID);
			IExtension[] extensions = point.getExtensions();
			for (int i=0;i < extensions.length;i++){
				IExtension ext = extensions[i];
				for (int j=0;j < ext.getConfigurationElements().length;j++){
					final String bundleId = ext.getConfigurationElements()[j].getContributor().getName();
					final String id = ext.getConfigurationElements()[j].getAttribute("typeid");
					final String klass = ext.getConfigurationElements()[j].getAttribute("class");
					registerFeature(bundleId, id, klass);
				}
			}
		} catch (InvalidRegistryObjectException e) {
			JSFCorePlugin.log(e, "Unable to read " + JSFCorePlugin.PLUGIN_ID + EXTPTID + " registry");
		}
	}
	
	/**
	 * Create {@link IMetaDataEnabledFeatureExtension}s and add to registry
	 * @param bundleID
	 * @param typeId
	 * @param klass
	 */
	protected void registerFeature(String bundleID, String typeId, String klass){
		IMetaDataEnabledFeatureExtension aFeature = new MetaDataEnabledFeatureExtension(bundleID, typeId, klass);
		if (canCreateTypeForFeatureExtension(aFeature)){
			if (!featuresMap.containsKey(typeId)){
				List list = new ArrayList();
				list.add(aFeature);
				featuresMap.put(typeId, list);
			}
			else {
				List list = featuresMap.get(typeId);
				list.add(aFeature);
			}
		}
	}


	private boolean canCreateTypeForFeatureExtension(IMetaDataEnabledFeatureExtension feature) {
		if (! typeCacheMap.containsKey(feature.getTypeID())){
			IType type = AttributeValueRuntimeTypeRegistry.getInstance().getType(feature.getTypeID());
			Class typeClass = AttributeValueRuntimeTypeFactory.getInstance().getClassForType(type);
			typeCacheMap.put(feature.getTypeID(), typeClass);
		}
		return typeCacheMap.get(feature.getTypeID()) != null;
	}

	/**
	 * @param typeId
	 * @return List of <code>AbstractMetaDataEnabledRuntimeTypeExtensions</code>
	 * for a given by type id
	 * 
	 * TODO: make more efficient... no need to keep calculating features for subtypes. 
	 */
	public List<IMetaDataEnabledFeatureExtension> getFeatures(String typeId) {
		
		if (!featuresMap.containsKey(typeId))
			featuresMap.put(typeId,new ArrayList());
		
		//copy current featuresMapped to typeId into return list
		List<IMetaDataEnabledFeatureExtension> srcList = featuresMap.get(typeId);
		List<IMetaDataEnabledFeatureExtension> ret = new ArrayList<IMetaDataEnabledFeatureExtension>(srcList.size());
		copy(ret, srcList);	
		
		List subs = getFeatureExtensionsForMatchingSubclass(typeId);
		for (Iterator<IMetaDataEnabledFeatureExtension> it=subs.iterator();it.hasNext();){
			IMetaDataEnabledFeatureExtension featureExt = it.next();
			if (!ret.contains(featureExt))
				ret.add(featureExt);
		}
		return ret;
		
	}
	
	private void copy(List<IMetaDataEnabledFeatureExtension> destList,
			List<IMetaDataEnabledFeatureExtension> srcList) {
		for (Iterator<IMetaDataEnabledFeatureExtension> it=srcList.iterator();it.hasNext();){
			destList.add(it.next());
		}
	}

	/**
	 * If the feature adapter is mapped to a type which is a superclass of the type of interest, then the feature adapter is an extension of that type
	 * @param typeId
	 * @return list of IMetaDataEnabledFeatureExtension
	 */
	private List<IMetaDataEnabledFeatureExtension> getFeatureExtensionsForMatchingSubclass(String typeId) {	
		IType type = AttributeValueRuntimeTypeRegistry.getInstance().getType(typeId);
		Class typeClass = AttributeValueRuntimeTypeFactory.getInstance().getClassForType(type);

		List<IMetaDataEnabledFeatureExtension> ret = new ArrayList<IMetaDataEnabledFeatureExtension>();
		// loop thru all of the type classes mapped to feature adapters that are subclasses of the type
		for (Iterator it=typeCacheMap.keySet().iterator();it.hasNext();){
			String featureTypeId = (String)it.next();
			Class featureTypeClass = typeCacheMap.get(featureTypeId);
			try {
//				if (featureTypeClass.equals(typeClass)){
//					ret.add(featureTypeClass);
//				}
//				else 
					if (typeClass.asSubclass(featureTypeClass) != null)	{	
					ret.addAll(featuresMap.get(featureTypeId));
				}						
			} catch (ClassCastException e) {//
			}
			
		}
		return ret;
	}
	

}
