/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * 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:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.dsl.xtext.lazyresolver.hook;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

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.IExtensionRegistry;
import org.eclipse.core.runtime.Platform;
import org.eclipse.xtext.util.Modules2;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.inject.Module;

/**
 * Delegates generation to registered extensions. See extensionpoint
 * "org.eclipse.osbp.dsl.xtext.lazyresolver.generatorDelegate"
 */
public class ExtensionsRuntimeModulesProvider {

	private static final Logger LOGGER = LoggerFactory
			.getLogger(ExtensionsRuntimeModulesProvider.class);

	private static final String ATTR_NAME = "runtimeModulesProvider"; //$NON-NLS-1$
	private static final String ATTR_GRAMMAR = "grammarName"; //$NON-NLS-1$
	private static final String ATTR_PRIO = "prio"; //$NON-NLS-1$
	private static final String ATTR_CLASS = "module"; //$NON-NLS-1$

	/**
	 * The instance. Using a singleton since extensions may only be available at
	 * platformlevel once.
	 */
	private static final ExtensionsRuntimeModulesProvider INSTANCE = new ExtensionsRuntimeModulesProvider();

	/**
	 * Returns the instance of the extension runtime modules provider.
	 * 
	 * @return the instance
	 */
	public static ExtensionsRuntimeModulesProvider getInstance() {
		return INSTANCE;
	}

	/**
	 * Returns a mixin of all provided modules. If no modules have been
	 * provided, <code>null</code> is returned.
	 * 
	 * @param grammarName
	 * @return
	 */
	public Module get(String grammarName) {
		List<Module> modules = readExtentions(grammarName);
		if (!modules.isEmpty()) {
			return Modules2.mixin(modules.toArray(new Module[modules.size()]));
		} else {
			return null;
		}
	}

	/**
	 * Extensions are being processed new for each request, since each call
	 * needs a new instance of inferrer.
	 * 
	 * @param grammarName
	 * @return
	 */
	private List<Module> readExtentions(String grammarName) {
		IExtensionRegistry registry = Platform.getExtensionRegistry();
		IExtensionPoint point = registry.getExtensionPoint(
				"org.eclipse.osbp.dsl.xtext.lazyresolver.api", ATTR_NAME);
		if (point == null) {
			return Collections.emptyList();
		}

		// filter extensions
		List<IConfigurationElement> temp = new ArrayList<IConfigurationElement>();
		IExtension[] extensions = point.getExtensions();
		for (int i = 0; i < extensions.length; i++) {
			IConfigurationElement[] elements = extensions[i]
					.getConfigurationElements();
			for (int j = 0; j < elements.length; j++) {
				String _grammarName = elements[j].getAttribute(ATTR_GRAMMAR);
				if (_grammarName != null && _grammarName.equals(grammarName)) {

					temp.add(elements[j]);

				}
			}
		}

		// sort the elements
		Collections.sort(temp, new Comparator<IConfigurationElement>() {
			@Override
			public int compare(IConfigurationElement o1,
					IConfigurationElement o2) {
				return o1.getAttribute(ATTR_PRIO).compareTo(
						o2.getAttribute(ATTR_PRIO));
			}
		});

		// create instances
		List<Module> delegates = new ArrayList<Module>(1);
		for (IConfigurationElement element : temp) {
			try {
				Module delegate = (Module) element
						.createExecutableExtension(ATTR_CLASS);
				delegates.add(delegate);
			} catch (CoreException e) {
				LOGGER.error("{}", e);
			}
		}

		return delegates;
	}

}
