/*******************************************************************************
 * Copyright (c) 2010, 2014 BestSolution.at and others.
 * 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:
 *     Tom Schindl<tom.schindl@bestsolution.at> - initial API and implementation
 *     Lars Vogel <Lars.Vogel@gmail.com> - Bug 430075, 430080, 431464, 433336
 *     René Brandstetter - Bug 419749 - [Workbench] [e4 Workbench] - Remove the deprecated PackageAdmin
 *     Brian de Alwis (MTI) - Bug 433053
 *     Florian Pirchner - adjusted for Vaaclipse perspectives restore - using different ModelUtils
 ******************************************************************************/

package org.eclipse.osbp.vaaclipse.addons.common.resource;

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

import javax.inject.Inject;

import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IContributor;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.e4.core.contexts.ContextInjectionFactory;
import org.eclipse.e4.core.contexts.EclipseContextFactory;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.di.annotations.Execute;
import org.eclipse.e4.core.services.contributions.IContributionFactory;
import org.eclipse.e4.core.services.log.Logger;
import org.eclipse.e4.ui.internal.workbench.E4XMIResource;
import org.eclipse.e4.ui.internal.workbench.ExtensionsSort;
import org.eclipse.e4.ui.internal.workbench.URIHelper;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.model.application.MApplicationElement;
import org.eclipse.e4.ui.model.fragment.MModelFragment;
import org.eclipse.e4.ui.model.fragment.MModelFragments;
import org.eclipse.e4.ui.model.fragment.MStringModelFragment;
import org.eclipse.e4.ui.model.fragment.impl.FragmentPackageImpl;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EContentsEList;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.osbp.vaaclipse.addons.common.api.model.VaaclipseModelUtils;

/**
 * The Class VaaclipseModelAssembler.
 */
@SuppressWarnings("restriction")
public class VaaclipseModelAssembler {
	
	/** The logger. */
	@Inject
	private Logger logger;

	/** The application. */
	@Inject
	private MApplication application;

	/** The context. */
	@Inject
	private IEclipseContext context;

	/** The registry. */
	@Inject
	private IExtensionRegistry registry;

	/** The Constant extensionPointID. */
	final private static String extensionPointID = "org.eclipse.e4.workbench.model"; //$NON-NLS-1$

	/** The Constant INITIAL. */
	//	private static final String ALWAYS = "always"; //$NON-NLS-1$
	private static final String INITIAL = "initial"; //$NON-NLS-1$ 
	
	/** The Constant NOTEXISTS. */
	private static final String NOTEXISTS = "notexists"; //$NON-NLS-1$ 

	/**
	 * Process the model.
	 *
	 * @param initial
	 *            the initial
	 */
	public void processModel(boolean initial) {
		IExtensionPoint extPoint = registry.getExtensionPoint(extensionPointID);
		IExtension[] extensions = new ExtensionsSort().sort(extPoint
				.getExtensions());

		List<MApplicationElement> imports = new ArrayList<MApplicationElement>();
		List<MApplicationElement> addedElements = new ArrayList<MApplicationElement>();

		// run processors which are marked to run before fragments
		runProcessors(extensions, initial, false);
		processFragments(extensions, imports, addedElements, initial);
		// run processors which are marked to run after fragments
		runProcessors(extensions, initial, true);

		resolveImports(imports, addedElements);
	}

	/**
	 * Process fragments.
	 *
	 * @param extensions
	 *            the extensions
	 * @param imports
	 *            the imports
	 * @param addedElements
	 *            the added elements
	 * @param initial
	 *            the initial
	 */
	private void processFragments(IExtension[] extensions,
			List<MApplicationElement> imports,
			List<MApplicationElement> addedElements, boolean initial) {

		for (IExtension extension : extensions) {
			IConfigurationElement[] ces = extension.getConfigurationElements();
			for (IConfigurationElement ce : ces) {
				if ("fragment".equals(ce.getName())) { //$NON-NLS-1$
					if (initial || !INITIAL.equals(ce.getAttribute("apply"))) { //$NON-NLS-1$ 
						processFragment(ce, imports, addedElements, initial);
					}
				}
			}
		}
	}

	/**
	 * Process fragment.
	 *
	 * @param ce
	 *            the ce
	 * @param imports
	 *            the imports
	 * @param addedElements
	 *            the added elements
	 * @param initial
	 *            the initial
	 */
	private void processFragment(IConfigurationElement ce,
			List<MApplicationElement> imports,
			List<MApplicationElement> addedElements, boolean initial) {
		E4XMIResource applicationResource = (E4XMIResource) ((EObject) application)
				.eResource();
		ResourceSet resourceSet = applicationResource.getResourceSet();
		IContributor contributor = ce.getContributor();
		String attrURI = ce.getAttribute("uri"); //$NON-NLS-1$
		String bundleName = contributor.getName();
		if (attrURI == null) {
			logger.warn(
					"Unable to find location for the model extension \"{0}\"", bundleName); //$NON-NLS-1$
			return;
		}

		URI uri;
		try {
			// check if the attrURI is already a platform URI
			if (URIHelper.isPlatformURI(attrURI)) {
				uri = URI.createURI(attrURI);
			} else {
				String path = bundleName + '/' + attrURI;
				uri = URI.createPlatformPluginURI(path, false);
			}
		} catch (RuntimeException e) {
			logger.warn(
					e,
					"Invalid location \"" + attrURI + "\" of model extension \"" + bundleName + "\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			return;
		}

		String contributorURI = URIHelper.constructPlatformURI(contributor);
		Resource resource;
		try {
			resource = resourceSet.getResource(uri, true);
		} catch (RuntimeException e) {
			logger.warn(
					e,
					"Unable to read model extension from \"" + uri.toString() + "\" of \"" + bundleName + "\""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			return;
		}

		EList<?> contents = resource.getContents();
		if (contents.isEmpty()) {
			return;
		}

		Object extensionRoot = contents.get(0);

		if (!(extensionRoot instanceof MModelFragments)) {
			logger.warn("Unable to create model extension \"{0}\"", bundleName); //$NON-NLS-1$
			return;
		}
		boolean checkExist = !initial
				&& NOTEXISTS.equals(ce.getAttribute("apply")); //$NON-NLS-1$ 

		MModelFragments fragmentsContainer = (MModelFragments) extensionRoot;
		List<MModelFragment> fragments = fragmentsContainer.getFragments();
		boolean evalImports = false;
		for (MModelFragment fragment : fragments) {
			List<MApplicationElement> elements = fragment.getElements();
			if (elements.size() == 0) {
				continue;
			}

			for (MApplicationElement el : elements) {
				EObject o = (EObject) el;

				E4XMIResource r = (E4XMIResource) o.eResource();

				if (checkExist
						&& applicationResource.getIDToEObjectMap().containsKey(
								r.getID(o))) {
					continue;
				}

				String cId = r.getID(o);
				applicationResource.setID(o, r.getID(o));
				String nId = applicationResource.getID(o);
				assert(cId.equals(nId));
				
				if (contributorURI != null)
					el.setContributorURI(contributorURI);

				// Remember IDs of subitems
				TreeIterator<EObject> treeIt = EcoreUtil
						.getAllContents(o, true);
				while (treeIt.hasNext()) {
					EObject eObj = treeIt.next();
					r = (E4XMIResource) eObj.eResource();
					if (contributorURI != null
							&& (eObj instanceof MApplicationElement))
						((MApplicationElement) eObj)
								.setContributorURI(contributorURI);
					applicationResource.setID(eObj, r.getInternalId(eObj));
				}
			}

			List<MApplicationElement> merged = merge(application, (MStringModelFragment) fragment);
			if (merged.size() > 0) {
				evalImports = true;
				addedElements.addAll(merged);
			} else {
				logger.info("Nothing to merge for \"{0}\"", uri); //$NON-NLS-1$
			}
		}

		if (evalImports) {
			List<MApplicationElement> localImports = fragmentsContainer
					.getImports();
			if (localImports != null) {
				imports.addAll(localImports);
			}
		}
	}
	
	/**
	 * Merge.
	 *
	 * @param application
	 *            the application
	 * @param fragment
	 *            the fragment
	 * @return the list
	 */
	public List<MApplicationElement> merge(MApplication application, MStringModelFragment fragment) {
		MApplicationElement o =  VaaclipseModelUtils.findElementById(application, fragment.getParentElementId());
		if( o != null ) {
			EStructuralFeature feature = ((EObject)o).eClass().getEStructuralFeature(fragment.getFeaturename());
			if( feature != null ) {
				return VaaclipseModelUtils.merge(o, feature, fragment.getElements(), fragment.getPositionInList());	
			}
			
		}
		
		return Collections.emptyList();
	}

	/**
	 * Run processors.
	 *
	 * @param extensions
	 *            the extensions
	 * @param initial
	 *            the initial
	 * @param afterFragments
	 *            the after fragments
	 */
	private void runProcessors(IExtension[] extensions, boolean initial,
			boolean afterFragments) {
		for (IExtension extension : extensions) {
			IConfigurationElement[] ces = extension.getConfigurationElements();
			for (IConfigurationElement ce : ces) {
				boolean parseBoolean = Boolean.parseBoolean(ce
						.getAttribute("beforefragment")); //$NON-NLS-1$
				if ("processor".equals(ce.getName()) && afterFragments != parseBoolean) { //$NON-NLS-1$
					if (initial || !INITIAL.equals(ce.getAttribute("apply"))) { //$NON-NLS-1$
						runProcessor(ce);
					}
				}
			}
		}
	}

	/**
	 * Run processor.
	 *
	 * @param ce
	 *            the ce
	 */
	private void runProcessor(IConfigurationElement ce) {
		IEclipseContext localContext = EclipseContextFactory.create();
		IContributionFactory factory = context.get(IContributionFactory.class);

		for (IConfigurationElement ceEl : ce.getChildren("element")) { //$NON-NLS-1$
			String id = ceEl.getAttribute("id"); //$NON-NLS-1$

			if (id == null) {
				logger.warn("No element id given"); //$NON-NLS-1$
				continue;
			}

			String key = ceEl.getAttribute("contextKey"); //$NON-NLS-1$
			if (key == null) {
				key = id;
			}

			MApplicationElement el = VaaclipseModelUtils
					.findElementById(application, id);
			if (el == null) {
				logger.warn("Could not find element with id '" + id + "'"); //$NON-NLS-1$ //$NON-NLS-2$
			}
			localContext.set(key, el);
		}

		try {
			Object o = factory
					.create("bundleclass://" + ce.getContributor().getName() + "/" + ce.getAttribute("class"), //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
							context, localContext);
			if (o == null) {
				logger.warn("Unable to create processor " + ce.getAttribute("class") + " from " + ce.getContributor().getName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
			} else {
				ContextInjectionFactory.invoke(o, Execute.class, context,
						localContext);
			}
		} catch (Exception e) {
			logger.warn(e, "Could not run processor"); //$NON-NLS-1$
		}
	}

	/**
	 * Resolve imports.
	 *
	 * @param imports
	 *            the imports
	 * @param addedElements
	 *            the added elements
	 */
	private void resolveImports(List<MApplicationElement> imports,
			List<MApplicationElement> addedElements) {
		if (imports.isEmpty())
			return;
		// now that we have all components loaded, resolve imports
		Map<MApplicationElement, MApplicationElement> importMaps = new HashMap<MApplicationElement, MApplicationElement>();
		for (MApplicationElement importedElement : imports) {
			MApplicationElement realElement = VaaclipseModelUtils.findElementById(
					application, importedElement.getElementId());
			if (realElement == null) {
				logger.warn("Could not resolve an import element for '" + realElement + "'"); //$NON-NLS-1$ //$NON-NLS-2$
			}

			importMaps.put(importedElement, realElement);
		}

		TreeIterator<EObject> it = EcoreUtil.getAllContents(addedElements);
		List<Runnable> commands = new ArrayList<Runnable>();

		// TODO Probably use EcoreUtil.UsageCrossReferencer
		while (it.hasNext()) {
			EObject o = it.next();

			EContentsEList.FeatureIterator<EObject> featureIterator = (EContentsEList.FeatureIterator<EObject>) o
					.eCrossReferences().iterator();
			while (featureIterator.hasNext()) {
				EObject importObject = featureIterator.next();
				if (importObject.eContainmentFeature() == FragmentPackageImpl.Literals.MODEL_FRAGMENTS__IMPORTS) {
					EStructuralFeature feature = featureIterator.feature();

					MApplicationElement el = importMaps.get(importObject);
					if (el == null) {
						logger.warn("Could not resolve import for " + el); //$NON-NLS-1$
					}

					final EObject interalTarget = o;
					final EStructuralFeature internalFeature = feature;
					final MApplicationElement internalElment = el;
					final EObject internalImportObject = importObject;

					commands.add(new Runnable() {

						@Override
						public void run() {
							if (internalFeature.isMany()) {
								logger.error("Replacing"); //$NON-NLS-1$
								@SuppressWarnings("unchecked")
								List<Object> l = (List<Object>) interalTarget
										.eGet(internalFeature);
								int index = l.indexOf(internalImportObject);
								if (index >= 0) {
									l.set(index, internalElment);
								}
							} else {
								interalTarget.eSet(internalFeature,
										internalElment);
							}
						}
					});
				}
			}
		}

		for (Runnable cmd : commands) {
			cmd.run();
		}
	}
}
