/*******************************************************************************
 * Copyright (c) 2015 Obeo.
 * 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:
 *    Obeo - initial API and implementation and/or initial documentation
 *    ...
 *******************************************************************************/
package org.eclipse.intent.mapping.ide;

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.IRegistryEventListener;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.intent.mapping.MappingUtils;
import org.eclipse.intent.mapping.base.BaseElementFactory;
import org.eclipse.intent.mapping.base.ContainerProviderFactory;
import org.eclipse.intent.mapping.base.IBase;
import org.eclipse.intent.mapping.base.ILocation;
import org.eclipse.intent.mapping.connector.IConnector;
import org.eclipse.intent.mapping.connector.IContainerProvider;
import org.eclipse.intent.mapping.ide.adapter.IMarkerToLocationDescriptor;
import org.eclipse.intent.mapping.ide.adapter.MarkerToLocationDescriptorAdapterFactory;
import org.eclipse.intent.mapping.ide.connector.IFileConnectorDelegate;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleException;

/**
 * This listener will allow us to be aware of contribution changes against the {@link ILocation} and
 * {@link IFileConnectorDelegate} extension points.
 *
 * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
 */
public class IdeMappingRegistryListener implements IRegistryEventListener {

	/**
	 * The class constant.
	 */
	public static final String CLASS = "class";

	/**
	 * {@link ILocation} extension point to parse for extensions.
	 */
	public static final String LOCATION_EXTENSION_POINT = "org.eclipse.intent.mapping.ide.location";

	/**
	 * {@link ILocation} tag.
	 */
	public static final String BASE_TAG_EXTENSION = "base";

	/**
	 * The {@link ILocation} extension point base attribute.
	 */
	public static final String BASE_ATTRIBUTE_CLASS = CLASS;

	/**
	 * {@link ILocation} tag.
	 */
	public static final String LOCATION_TAG_EXTENSION = "location";

	/**
	 * {@link ILocation} tag.
	 */
	public static final String LOCATION_ATTRIBUTE_INTERFACE = "interface";

	/**
	 * {@link ILocation} tag.
	 */
	public static final String LOCATION_ATTRIBUTE_IMPLEMENTATION = "implementation";

	/**
	 * {@link IFileConnectorDelegate} extension point to parse for extensions.
	 */
	public static final String FILE_CONNECTOR_DELEGATE_EXTENSION_POINT = "org.eclipse.intent.mapping.ide.fileConnectorDelegate";

	/**
	 * {@link IFileConnectorDelegate} tag.
	 */
	public static final String FILE_CONNECTOR_DELEGATE_TAG_EXTENSION = "fileConnectorDelegate";

	/**
	 * The {@link ILocation} extension point base attribute.
	 */
	public static final String FILE_CONNECTOR_DELEGATE_ATTRIBUTE_CLASS = CLASS;

	/**
	 * Plugin providing {@link IBase} extension point to parse for extensions.
	 */
	public static final String BASE_PROVIDER_EXTENSION_POINT = "org.eclipse.intent.mapping.ide.baseProvider";

	/**
	 * Plugin providing {@link IConnector} extension point to parse for extensions.
	 */
	public static final String CONNECTOR_EXTENSION_POINT = "org.eclipse.intent.mapping.ide.connector";

	/**
	 * {@link IConnector} tag.
	 */
	public static final String CONNECTOR_TAG_EXTENSION = "connector";

	/**
	 * The {@link ILocation} extension point connector attribute.
	 */
	public static final String CONNECTOR_ATTRIBUTE_CLASS = CLASS;

	/**
	 * Plugin providing {@link IMarkerToLocationDescriptor} extension point to parse for extensions.
	 */
	public static final String MARKER_TO_LOCATION_EXTENSION_POINT = "org.eclipse.intent.mapping.ide.markerToLocation";

	/**
	 * {@link IMarkerToLocationDescriptor} tag.
	 */
	public static final String MARKER_TO_LOCATION_TAG_EXTENSION = "markerToLocation";

	/**
	 * The {@link IMarkerToLocationDescriptor} extension point adapter attribute.
	 */
	public static final String MARKER_TO_LOCATION_ATTRIBUTE_CLASS = CLASS;

	/**
	 * The {@link IMarkerToLocationDescriptor} extension point adapter attribute.
	 */
	public static final String MARKER_TO_LOCATION_ATTRIBUTE_MARKER_TYPE = "markerType";

	/**
	 * {@link IContainerProvider} extension point to parse for extensions.
	 */
	public static final String CONTAINER_PROVIDER_EXTENSION_POINT = "org.eclipse.intent.mapping.ide.containerProvider";

	/**
	 * {@link IContainerProvider} tag.
	 */
	public static final String CONTAINER_PROVIDER_TAG_EXTENSION = "provider";

	/**
	 * The {@link IContainerProvider} extension point base attribute.
	 */
	public static final String CONTAINER_PROVIDER_ATTRIBUTE_CLASS = CLASS;

	/**
	 * An {@link BaseElementFactory.FactoryDescriptor} for an extension point.
	 * 
	 * @param <T>
	 *            the kind of {@link ILocation}
	 * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
	 */
	public static class ExtensionFactoryDescriptor<T extends ILocation> implements BaseElementFactory.IFactoryDescriptor<T> {

		/**
		 * The {@link IConfigurationElement}.
		 */
		private final IConfigurationElement element;

		/**
		 * Constructor.
		 * 
		 * @param element
		 *            the {@link IConfigurationElement}
		 */
		public ExtensionFactoryDescriptor(IConfigurationElement element) {
			this.element = element;
		}

		/**
		 * {@inheritDoc}
		 *
		 * @see org.eclipse.intent.mapping.base.BaseElementFactory.IFactoryDescriptor#createElement()
		 */
		@SuppressWarnings("unchecked")
		public T createElement() throws InstantiationException, IllegalAccessException,
				ClassNotFoundException {
			try {
				return (T)element.createExecutableExtension(LOCATION_ATTRIBUTE_IMPLEMENTATION);
			} catch (CoreException e) {
				Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e
						.getMessage(), e));
			}
			return null;
		}

	}

	/**
	 * An {@link ContainerProviderFactory.FactoryDescriptor} for an extension point.
	 * 
	 * @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
	 */
	public static class ExtensionContainerProviderFactoryDescriptor implements ContainerProviderFactory.IFactoryDescriptor {

		/**
		 * The {@link IConfigurationElement}.
		 */
		private final IConfigurationElement element;

		/**
		 * Constructor.
		 * 
		 * @param element
		 *            the {@link IConfigurationElement}
		 */
		public ExtensionContainerProviderFactoryDescriptor(IConfigurationElement element) {
			this.element = element;
		}

		/**
		 * {@inheritDoc}
		 *
		 * @see org.eclipse.intent.mapping.base.BaseElementFactory.IFactoryDescriptor#createElement()
		 */
		public IContainerProvider createElement() throws InstantiationException, IllegalAccessException,
				ClassNotFoundException {
			try {
				return (IContainerProvider)element.createExecutableExtension(
						CONTAINER_PROVIDER_ATTRIBUTE_CLASS);
			} catch (CoreException e) {
				Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e
						.getMessage(), e));
			}
			return null;
		}

		/**
		 * {@inheritDoc}
		 *
		 * @see org.eclipse.intent.mapping.base.ContainerProviderFactory.IFactoryDescriptor#getClassName()
		 */
		public String getClassName() {
			return element.getAttribute(CONTAINER_PROVIDER_ATTRIBUTE_CLASS);
		}

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.core.runtime.IRegistryEventListener#added(org.eclipse.core.runtime.IExtension[])
	 */
	public void added(IExtension[] extensions) {
		for (IExtension extension : extensions) {
			if (LOCATION_EXTENSION_POINT.equals(extension.getUniqueIdentifier())) {
				parseLocationExtension(extension);
			} else if (FILE_CONNECTOR_DELEGATE_EXTENSION_POINT.equals(extension.getUniqueIdentifier())) {
				parseFileConnectorDelegateExtension(extension);
			} else if (BASE_PROVIDER_EXTENSION_POINT.equals(extension.getUniqueIdentifier())) {
				parseBaseProviderExtension(extension);
			} else if (CONNECTOR_EXTENSION_POINT.equals(extension.getUniqueIdentifier())) {
				parseConnectorProviderExtension(extension);
			} else if (MARKER_TO_LOCATION_EXTENSION_POINT.equals(extension.getUniqueIdentifier())) {
				parseMarkerToLocationExtension(extension);
			} else if (CONTAINER_PROVIDER_EXTENSION_POINT.equals(extension.getUniqueIdentifier())) {
				parseContainerProviderExtension(extension);
			}
		}
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.core.runtime.IRegistryEventListener#added(org.eclipse.core.runtime.IExtensionPoint[])
	 */
	public void added(IExtensionPoint[] extensionPoints) {
		// no need to listen to this event
	}

	/**
	 * Though this listener reacts to the extension point changes, there could have been contributions before
	 * it's been registered. This will parse these initial contributions.
	 */
	public void parseInitialContributions() {
		final IExtensionRegistry registry = Platform.getExtensionRegistry();

		for (IExtension extension : registry.getExtensionPoint(CONTAINER_PROVIDER_EXTENSION_POINT)
				.getExtensions()) {
			parseContainerProviderExtension(extension);
		}
		for (IExtension extension : registry.getExtensionPoint(FILE_CONNECTOR_DELEGATE_EXTENSION_POINT)
				.getExtensions()) {
			parseFileConnectorDelegateExtension(extension);
		}
		for (IExtension extension : registry.getExtensionPoint(CONNECTOR_EXTENSION_POINT).getExtensions()) {
			parseConnectorProviderExtension(extension);
		}
		for (IExtension extension : registry.getExtensionPoint(MARKER_TO_LOCATION_EXTENSION_POINT)
				.getExtensions()) {
			parseMarkerToLocationExtension(extension);
		}
		for (IExtension extension : registry.getExtensionPoint(LOCATION_EXTENSION_POINT).getExtensions()) {
			parseLocationExtension(extension);
		}
		for (IExtension extension : registry.getExtensionPoint(BASE_PROVIDER_EXTENSION_POINT)
				.getExtensions()) {
			parseBaseProviderExtension(extension);
		}
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.core.runtime.IRegistryEventListener#removed(org.eclipse.core.runtime.IExtension[])
	 */
	@SuppressWarnings("unchecked")
	public void removed(IExtension[] extensions) {
		for (IExtension extension : extensions) {
			final IConfigurationElement[] configElements = extension.getConfigurationElements();
			for (IConfigurationElement elem : configElements) {
				if (BASE_TAG_EXTENSION.equals(elem.getName())) {
					final Bundle contributor = Platform.getBundle(elem.getContributor().getName());
					final String baseClassName = elem.getAttribute(BASE_ATTRIBUTE_CLASS);
					try {
						Class<? extends IBase> baseClass = (Class<? extends IBase>)contributor.loadClass(
								baseClassName);
						for (IConfigurationElement locationElem : elem.getChildren(LOCATION_TAG_EXTENSION)) {
							final String interfaceClassName = locationElem.getAttribute(
									LOCATION_ATTRIBUTE_INTERFACE);
							Class<ILocation> interfaceClass = (Class<ILocation>)contributor.loadClass(
									interfaceClassName);
							MappingUtils.unregisterLocationImplementation(baseClass, interfaceClass);
						}
					} catch (ClassNotFoundException e) {
						Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e
								.getMessage(), e));
					}
				} else if (FILE_CONNECTOR_DELEGATE_TAG_EXTENSION.equals(elem.getName())) {
					final String delegateClassName = elem.getAttribute(
							FILE_CONNECTOR_DELEGATE_ATTRIBUTE_CLASS);
					IFileConnectorDelegate delegateToRemove = null;
					for (IFileConnectorDelegate delegate : IdeMappingUtils.getFileConectorDelegateRegistry()
							.getConnectorDelegates()) {
						if (delegateClassName.equals(delegate.getClass().getName())) {
							delegateToRemove = delegate;
							break;
						}
					}
					if (delegateToRemove != null) {
						IdeMappingUtils.getFileConectorDelegateRegistry().unregister(delegateToRemove);
					}
				} else if (CONTAINER_PROVIDER_TAG_EXTENSION.equals(elem.getName())) {
					MappingUtils.getContainerProviderFactory().removeDescriptor(elem.getAttribute(
							CONTAINER_PROVIDER_ATTRIBUTE_CLASS));
				}
			}
		}
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.eclipse.core.runtime.IRegistryEventListener#removed(org.eclipse.core.runtime.IExtensionPoint[])
	 */
	public void removed(IExtensionPoint[] extensionPoints) {
		// no need to listen to this event
	}

	/**
	 * Parses a single {@link ILocation} extension contribution.
	 * 
	 * @param extension
	 *            Parses the given extension and adds its contribution to the registry
	 */
	@SuppressWarnings("unchecked")
	private void parseLocationExtension(IExtension extension) {
		final IConfigurationElement[] configElements = extension.getConfigurationElements();
		for (IConfigurationElement elem : configElements) {
			if (BASE_TAG_EXTENSION.equals(elem.getName())) {
				final Bundle contributor = Platform.getBundle(elem.getContributor().getName());
				final String baseClassName = elem.getAttribute(BASE_ATTRIBUTE_CLASS);
				try {
					Class<? extends IBase> baseClass = (Class<? extends IBase>)contributor.loadClass(
							baseClassName);
					for (IConfigurationElement locationElem : elem.getChildren(LOCATION_TAG_EXTENSION)) {
						final String interfaceClassName = locationElem.getAttribute(
								LOCATION_ATTRIBUTE_INTERFACE);
						Class<ILocation> interfaceClass = (Class<ILocation>)contributor.loadClass(
								interfaceClassName);
						MappingUtils.registerLocationImplementation(baseClass, interfaceClass,
								new ExtensionFactoryDescriptor<ILocation>(locationElem));
					}
				} catch (ClassNotFoundException e) {
					Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e
							.getMessage(), e));
				}
			}
		}
	}

	/**
	 * Parses a single {@link IFileConnectorDelegate} extension contribution.
	 * 
	 * @param extension
	 *            Parses the given extension and adds its contribution to the registry
	 */
	private void parseFileConnectorDelegateExtension(IExtension extension) {
		final IConfigurationElement[] configElements = extension.getConfigurationElements();
		for (IConfigurationElement elem : configElements) {
			if (FILE_CONNECTOR_DELEGATE_TAG_EXTENSION.equals(elem.getName())) {
				try {
					final IFileConnectorDelegate delegate = (IFileConnectorDelegate)elem
							.createExecutableExtension(FILE_CONNECTOR_DELEGATE_ATTRIBUTE_CLASS);
					IdeMappingUtils.getFileConectorDelegateRegistry().register(delegate);
				} catch (CoreException e) {
					Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e
							.getMessage(), e));
				}
			}
		}
	}

	/**
	 * Parses a single {@link IBase} extension contribution.
	 * 
	 * @param extension
	 *            Parses the given extension and adds its contribution to the registry.
	 */
	private void parseBaseProviderExtension(IExtension extension) {
		final String bundleName = extension.getContributor().getName();
		final Bundle bundle = Platform.getBundle(bundleName);
		try {
			if (bundle.getState() != Bundle.ACTIVE) {
				bundle.start();
			}
		} catch (BundleException e) {
			Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage(),
					e));
		}
	}

	/**
	 * Parses a single {@link IConnector} extension contribution.
	 * 
	 * @param extension
	 *            Parses the given extension and adds its contribution to the registry
	 */
	private void parseConnectorProviderExtension(IExtension extension) {
		final IConfigurationElement[] configElements = extension.getConfigurationElements();
		for (IConfigurationElement elem : configElements) {
			if (CONNECTOR_TAG_EXTENSION.equals(elem.getName())) {
				try {
					final IConnector connector = (IConnector)elem.createExecutableExtension(
							CONNECTOR_ATTRIBUTE_CLASS);
					MappingUtils.getConnectorRegistry().register(connector);
				} catch (CoreException e) {
					Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e
							.getMessage(), e));
				}
			}
		}
	}

	/**
	 * Parses a single {@link IMarkerToLocationDescriptor} extension contribution.
	 * 
	 * @param extension
	 *            Parses the given extension and adds its contribution to the registry
	 */
	private void parseMarkerToLocationExtension(IExtension extension) {
		final IConfigurationElement[] configElements = extension.getConfigurationElements();
		for (IConfigurationElement elem : configElements) {
			if (MARKER_TO_LOCATION_TAG_EXTENSION.equals(elem.getName())) {
				try {
					final String marterType = elem.getAttribute(MARKER_TO_LOCATION_ATTRIBUTE_MARKER_TYPE);
					final IMarkerToLocationDescriptor adapter = (IMarkerToLocationDescriptor)elem
							.createExecutableExtension(MARKER_TO_LOCATION_ATTRIBUTE_CLASS);
					MarkerToLocationDescriptorAdapterFactory.register(adapter, marterType);
				} catch (CoreException e) {
					Activator.getDefault().getLog().log(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e
							.getMessage(), e));
				}
			}
		}
	}

	/**
	 * Parses a single {@link IContainerProvider} extension contribution.
	 * 
	 * @param extension
	 *            Parses the given extension and adds its contribution to the registry
	 */
	private void parseContainerProviderExtension(IExtension extension) {
		final IConfigurationElement[] configElements = extension.getConfigurationElements();
		for (IConfigurationElement elem : configElements) {
			if (CONTAINER_PROVIDER_TAG_EXTENSION.equals(elem.getName())) {
				MappingUtils.getContainerProviderFactory().addDescriptor(
						new ExtensionContainerProviderFactoryDescriptor(elem));
			}
		}
	}

}
