/*******************************************************************************
 * Copyright (c) 2007 BEA Systems, Inc. 
 * 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:
 *    wharley@bea.com - initial API and implementation
 *    
 *******************************************************************************/

package org.eclipse.jdt.apt.core.internal;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.apt.core.internal.util.FactoryContainer;
import org.eclipse.jdt.apt.core.internal.util.FactoryPath;

import com.sun.mirror.apt.AnnotationProcessorFactory;

/**
 * Manages caches of plugins which provide annotation processors.
 * 
 * @since 3.3
 */
public class FactoryPluginManager {
	/** 
	 * Map of factory names -> factories.  A single plugin factory container may 
	 * contain multiple annotation processor factories, each with a unique name.
	 * To support lazy initialization, this should only be accessed by calling
	 * @see #getJava5PluginFactoryMap() . 
	 */
	private static final HashMap<String, AnnotationProcessorFactory> PLUGIN_JAVA5_FACTORY_MAP = new HashMap<String, AnnotationProcessorFactory>();
	
	/** 
	 * Map of factory names -> factories.  A single plugin factory container may 
	 * contain multiple annotation processor factories, each with a unique name.
	 * To support lazy initialization, this should only be accessed by calling
	 * @see #getJava5PluginFactoryMap() . 
	 */
	private static final HashMap<String, IServiceFactory> PLUGIN_JAVA6_FACTORY_MAP = new HashMap<String, IServiceFactory>();

	/** 
	 * Map of plugin names -> plugin factory containers, sorted by plugin name.
	 * A plugin that contains annotation processor factories (and extends the
	 * corresponding extension point) is a "plugin factory container".  
	 * To support lazy initialization, this should only be accessed by calling
	 * @see #getPluginFactoryContainerMap() . 
	 */
	private static final TreeMap<String, PluginFactoryContainer> PLUGIN_CONTAINER_MAP = new TreeMap<String, PluginFactoryContainer>();

	/** 
	 * true if PLUGIN_FACTORY_MAP and PLUGIN_CONTAINER_MAP have been initialized,
	 * by calling @see #loadPluginFactories() .
	 */
	private static boolean mapsInitialized = false;
	
	/**
	 * Returns an ordered list of all the plugin factory containers that have 
	 * been registered as plugins.  Note that this may include plugins that have 
	 * been disabled by the user's configuration.  The 'enabled' attribute in the
	 * returned map reflects the 'enableDefault' attribute in the plugin
	 * manifest, rather than the user configuration.  
	 * Ordering is alphabetic by plugin id.
	 */
	public static synchronized Map<FactoryContainer, FactoryPath.Attributes> getAllPluginFactoryContainers()
	{
		Map<FactoryContainer, FactoryPath.Attributes> map = 
			new LinkedHashMap<FactoryContainer, FactoryPath.Attributes>(getPluginContainerMap().size());
		for (PluginFactoryContainer pfc : getPluginContainerMap().values()) {
			FactoryPath.Attributes a = new FactoryPath.Attributes(pfc.getEnableDefault(), false);
			map.put(pfc, a);
		}
		return map;
	}
	
	public static synchronized AnnotationProcessorFactory getJava5FactoryFromPlugin( String factoryName )
	{
		AnnotationProcessorFactory apf = getJava5PluginFactoryMap().get( factoryName );
		if ( apf == null ) 
		{
			String s = "could not find AnnotationProcessorFactory " +  //$NON-NLS-1$
				factoryName + " from available factories defined by plugins"; //$NON-NLS-1$
			AptPlugin.log(new Status(IStatus.WARNING, AptPlugin.PLUGIN_ID, AptPlugin.STATUS_NOTOOLSJAR, s, null));
		}
		return apf;
	}

	public static synchronized IServiceFactory getJava6FactoryFromPlugin( String factoryName )
	{
		IServiceFactory isf = getJava6PluginFactoryMap().get( factoryName );
		if ( isf == null ) 
		{
			String s = "could not find annotation processor " +  //$NON-NLS-1$
				factoryName + " from available factories defined by plugins"; //$NON-NLS-1$
			AptPlugin.log(new Status(IStatus.WARNING, AptPlugin.PLUGIN_ID, AptPlugin.STATUS_NOTOOLSJAR, s, null));
		}
		return isf;
	}

	/**
     * Return the factory container corresponding to the specified plugin id.
     * All plugin factories are loaded at startup time.
     * @param pluginId the id of a plugin that extends annotationProcessorFactory.
     * @return a PluginFactoryContainer, or null if the plugin id does not 
     * identify an annotation processor plugin.
     */
	public static synchronized FactoryContainer getPluginFactoryContainer(String pluginId) {
		return getPluginContainerMap().get(pluginId);
	}
	
	/**
	 * Get the alphabetically sorted map of plugin names to plugin factory containers.
	 * Load plugins if the map has not yet been initialized.
	 */
	private static TreeMap<String, PluginFactoryContainer> getPluginContainerMap() {
		loadFactoryPlugins();
		return PLUGIN_CONTAINER_MAP;
	}
	
	/**
	 * Get the map of plugin factory names to plugin factories.
	 * Load plugins if the map has not yet been initialized.
	 */
	private static HashMap<String, AnnotationProcessorFactory> getJava5PluginFactoryMap() {
		loadFactoryPlugins();
		return PLUGIN_JAVA5_FACTORY_MAP;
	}

	/**
	 * Get the map of plugin factory names to plugin factories.
	 * Load plugins if the map has not yet been initialized.
	 */
	private static HashMap<String, IServiceFactory> getJava6PluginFactoryMap() {
		loadFactoryPlugins();
		return PLUGIN_JAVA6_FACTORY_MAP;
	}

    /**
	 * Discover and instantiate annotation processor factories by searching for plugins
	 * which contribute to org.eclipse.jdt.apt.core.annotationProcessorFactory.
	 * The first time this method is called, it will load all the plugin factories.
	 * Subsequent calls will be ignored.
	 */
	private static synchronized void loadFactoryPlugins() {
		if (mapsInitialized) {
			return;
		}
		IExtensionPoint extensionPoint = Platform.getExtensionRegistry().getExtensionPoint(
				AptPlugin.PLUGIN_ID, // name of plugin that exposes this extension point
				"annotationProcessorFactory"); //$NON-NLS-1$ - extension id

		// Iterate over all declared extensions of this extension point.  
		// A single plugin may extend the extension point more than once, although it's not recommended.
		for (IExtension extension : extensionPoint.getExtensions())
		{
			// Iterate over the children of the extension to find one named "factories".
			for(IConfigurationElement factories : extension.getConfigurationElements())
			{
				if ("factories".equals(factories.getName())) { //$NON-NLS-1$ - name of configElement 
					loadJava5Factories(extension, factories);
				}
				else if ("java6processors".equals(factories.getName())) { //$NON-NLS-1$ - name of configElement
					loadJava6Factories(extension, factories);
				}
				
			}
		}
		mapsInitialized = true;
	}

	private static void loadJava6Factories(IExtension extension, IConfigurationElement factories) {
		if (!AptPlugin.canRunJava6Processors()) {
			return;
		}
		
		// Get enableDefault.  If the attribute is missing, default to true.
		String enableDefaultStr = factories.getAttribute("enableDefault"); //$NON-NLS-1$
		boolean enableDefault = true;
		if ("false".equals(enableDefaultStr)) { //$NON-NLS-1$
			enableDefault = false;
		}
		
		// Create and cache a PluginFactoryContainer for this plugin.
		String pluginId = extension.getNamespaceIdentifier();
		//TODO: level problem.  In the extension point, enableDefault is associated with element, not ext point.
		PluginFactoryContainer pfc = new PluginFactoryContainer(pluginId, enableDefault);
		PLUGIN_CONTAINER_MAP.put(pluginId, pfc);
		
		// Iterate over the children of the "java6processors" element to find all the ones named "java6processor".
		for (IConfigurationElement factory : factories.getChildren()) {
			if (!"java6processor".equals(factory.getName())) { //$NON-NLS-1$
				continue;
			}
			String factoryName = null;
			try {
				factoryName = factory.getAttribute("class"); //$NON-NLS-1$
				Object execExt = factory.createExecutableExtension("class"); //$NON-NLS-1$ - attribute name
				Class<?> clazz = execExt.getClass();
				if (AptPlugin.getJava6ProcessorClass().isInstance(execExt)){
					assert(clazz.getName().equals(factoryName));
					IServiceFactory isf = new ClassServiceFactory(clazz);
					PLUGIN_JAVA6_FACTORY_MAP.put( factoryName, isf );
					pfc.addFactoryName(factoryName, AptPlugin.JAVA6_FACTORY_NAME);
				}
				else {
					reportFailureToLoadProcessor(null, factoryName, extension.getNamespaceIdentifier());
				}
			} catch(CoreException e) {
				reportFailureToLoadProcessor(e, factoryName, extension.getNamespaceIdentifier());
			}
		}
	}
	
	private static void loadJava5Factories(IExtension extension, IConfigurationElement factories) {
		// Get enableDefault.  If the attribute is missing, default to true.
		String enableDefaultStr = factories.getAttribute("enableDefault"); //$NON-NLS-1$
		boolean enableDefault = true;
		if ("false".equals(enableDefaultStr)) { //$NON-NLS-1$
			enableDefault = false;
		}
		
		// Create and cache a PluginFactoryContainer for this plugin.
		String pluginId = extension.getNamespaceIdentifier();
		PluginFactoryContainer pfc = new PluginFactoryContainer(pluginId, enableDefault);
		PLUGIN_CONTAINER_MAP.put(pluginId, pfc);
		
		// Iterate over the children of the "factories" element to find all the ones named "factory".
		for (IConfigurationElement factory : factories.getChildren()) {
			if (!"factory".equals(factory.getName())) { //$NON-NLS-1$
				continue;
			}
			String factoryName = null;
			try {
				factoryName = factory.getAttribute("class"); //$NON-NLS-1$
				Object execExt = factory.createExecutableExtension("class"); //$NON-NLS-1$ - attribute name
				if (execExt instanceof AnnotationProcessorFactory){
					assert(execExt.getClass().getName().equals(factoryName));
					PLUGIN_JAVA5_FACTORY_MAP.put( factoryName, (AnnotationProcessorFactory)execExt );
					pfc.addFactoryName(factoryName, AptPlugin.JAVA5_FACTORY_NAME);
				}
				else {
					reportFailureToLoadProcessor(null, factory.getName(), extension.getNamespaceIdentifier());
				}
			} catch(CoreException e) {
				reportFailureToLoadProcessor(e, factory.getName(), extension.getNamespaceIdentifier());
			}
		}
	}
	
	private static void reportFailureToLoadProcessor(Exception e, String factoryName, String pluginId) {
		AptPlugin.log(e, "Unable to load annotation processor "+ factoryName + //$NON-NLS-1$
				" from plug-in " + pluginId); //$NON-NLS-1$
	}
	
	
}
