/*******************************************************************************
 * 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());
			if (type != null){
				Class typeClass = AttributeValueRuntimeTypeFactory.getInstance().getClassForType(type);
				typeCacheMap.put(feature.getTypeID(), typeClass);
			}
			else
				return false;
		}
		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;
	}
	

}
