/*****************************************************************************
 * Copyright (c) 2019 CEA LIST, and others.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *   Nicolas FAUVERGUE (CEA LIST) nicolas.fauvergue@cea.fr - Initial API and implementation
 *
 *****************************************************************************/
package org.eclipse.papyrus.gitlight.compare.ui;

import static java.lang.String.format;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EContentAdapter;
import org.eclipse.emf.ecore.util.InternalEList;
import org.eclipse.emf.ecore.xmi.XMLResource;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.gmf.runtime.notation.NotationPackage;
import org.eclipse.papyrus.infra.emf.gmf.util.GMFUnsafe;
import org.eclipse.papyrus.infra.gmfdiag.common.model.NotationModel;
import org.eclipse.papyrus.infra.gmfdiag.common.reconciler.DiagramReconciler;
import org.eclipse.papyrus.infra.gmfdiag.common.reconciler.DiagramReconcilersReader;
import org.eclipse.papyrus.infra.gmfdiag.common.reconciler.DiagramVersioningUtils;

/**
 * Hook in the EMF Compare {@link ResourceSet} in order to make it able to handle papyrus diagram migration
 * features.
 */
public class DiagramMigrationHook extends AbstractPapyrusResourceSetHook {

	@Override
	public void preLoadingHook(ResourceSet resourceSet, Collection<? extends URI> uris) {
		// Pass
	}

	@Override
	public void postLoadingHook(ResourceSet resourceSet, Collection<? extends URI> uris) {
		for (Resource resource : new ArrayList<Resource>(resourceSet.getResources())) {
			if (NotationModel.NOTATION_FILE_EXTENSION.equals(resource.getURI().fileExtension())) {
				EList<EObject> contents = resource.getContents();
				for (EObject object : contents) {
					if (object instanceof Diagram) {
						Diagram diagram = (Diagram)object;
						IDGenerator idgen = new IDGenerator(diagram);
						try {
							migrateDiagram(getEditingDomain(resourceSet), diagram);
						} finally {
							idgen.dispose();
						}
					}
				}
			}
		}
	}

	/**
	 * Get the editing domain for this resourceSet or create it.
	 * 
	 * @param resourceSet
	 *            The resource set
	 * @return TransactionalEditingDomain
	 */
	private TransactionalEditingDomain getEditingDomain(ResourceSet resourceSet) {
		TransactionalEditingDomain existingDomain = TransactionalEditingDomain.Factory.INSTANCE
				.getEditingDomain(resourceSet);
		if (existingDomain == null) {
			return TransactionalEditingDomain.Factory.INSTANCE.createEditingDomain(resourceSet);
		} else {
			return existingDomain;
		}
	}

	/**
	 * Build the migration command.
	 * 
	 * @param diagram
	 *            Diagram you want to migrate
	 * @return CompositeCommand
	 */
	private CompositeCommand buildCommand(Diagram diagram) {
		CompositeCommand reconcileCommand = null;

		if (!DiagramVersioningUtils.isOfCurrentPapyrusVersion(diagram)) {
			reconcileCommand = new CompositeCommand("Reconciling"); //$NON-NLS-1$

			String sourceVersion = DiagramVersioningUtils.getCompatibilityVersion(diagram);
			Map<String, Collection<DiagramReconciler>> diagramReconcilers = DiagramReconcilersReader
					.getInstance().load();
			String diagramType = diagram.getType();
			Collection<DiagramReconciler> reconcilers = new LinkedList<DiagramReconciler>();
			if (diagramReconcilers.containsKey(diagramType)) {
				reconcilers.addAll(diagramReconcilers.get(diagramType));
			}

			boolean someFailed = false;
			Iterator<DiagramReconciler> reconciler = reconcilers.iterator();
			while (reconciler.hasNext() && !someFailed) {
				DiagramReconciler next = reconciler.next();

				if (!next.canReconcileFrom(diagram, sourceVersion)) {
					// asked for ignore it for this instance, all fine
					continue;
				}
				ICommand nextCommand = next.getReconcileCommand(diagram);
				if (nextCommand == null) {
					// legitimate no-op response, all fine
					continue;
				}

				if (nextCommand.canExecute()) {
					reconcileCommand.add(nextCommand);
				} else {
					PapyrusCompareUIPlugin.getDefault().getLog().log(new Status(IStatus.ERROR,
							PapyrusCompareUIPlugin.PLUGIN_ID,
							"Diagram reconciler " + next + " failed to reconcile diagram: " + diagram)); //$NON-NLS-1$ //$NON-NLS-2$
					someFailed = true;
				}
			}
			if (someFailed) {
				reconcileCommand = null;
			}
		}
		return reconcileCommand;
	}

	/**
	 * Migrate the diagram to the current version of Papyrus.
	 * 
	 * @param domain
	 *            The editing domain for this diagram.
	 * @param diagram
	 *            The diagram.
	 */
	private void migrateDiagram(TransactionalEditingDomain domain, Diagram diagram) {
		CompositeCommand migrationCommand = buildCommand(diagram);
		if (migrationCommand == null) {
			domain.dispose();
			return;
		}

		migrationCommand.add(DiagramVersioningUtils.createStampCurrentVersionCommand(diagram));
		// TODO: Handle reconcile exception
		try {
			// The migration command requires a transactional editing domain, but we don't
			// want to record anything for undo/redo etc.
			GMFUnsafe.write(domain, migrationCommand);
		} catch (Exception e) {
			logException(e);
		} finally {
			domain.dispose();
		}
	}

	/**
	 * Logs the specified exception.
	 * 
	 * @param t
	 *            The exception to be logged.
	 */
	private static void logException(Throwable t) {
		PapyrusCompareUIPlugin.getDefault().getLog()
				.log(new Status(IStatus.WARNING, PapyrusCompareUIPlugin.PLUGIN_ID,
						"Could not migrate the diagram before comparison", t)); //$NON-NLS-1$
	}

	//
	// Nested types
	//

	/**
	 * An adapter that generates new unique IDs, using a stable algorithm, for all new objects created by
	 * diagram migration. This helps to ensure that when the same diagram on multiple sides of a comparison is
	 * migrated on each side, that new elements created by migration are matched to avoid spurious add-add
	 * conflicts.
	 *
	 * @author Christian W. Damus
	 */
	protected static class IDGenerator extends EContentAdapter {
		private static final Pattern NOT_NCNAME = Pattern.compile("[^-a-zA-Z0-9_.]"); //$NON-NLS-1$

		private static final String CHILDREN_PAT = "%s.%d"; //$NON-NLS-1$

		private static final String STYLES_PAT = "%s._%s"; //$NON-NLS-1$

		private static final String OTHER_PAT = "%s.%s%d"; //$NON-NLS-1$

		private final Matcher notNCName = NOT_NCNAME.matcher(""); //$NON-NLS-1$

		private final EObject root;

		// Papyrus diagrams do not support cross-resource containment
		private XMLResource resource;

		private boolean enabled;

		/**
		 * Initializes me for generation of predictable, matchable unique identifiers in the tree under the
		 * given {@code root}.
		 * 
		 * @param root
		 *            the root of a tree in which to generate unique identifiers
		 */
		public IDGenerator(EObject root) {
			super();

			this.root = root;
			this.resource = (XMLResource)root.eResource();

			root.eAdapters().add(this);
			this.enabled = true;
		}

		public void dispose() {
			this.enabled = false;
			root.eAdapters().remove(this);
		}

		@Override
		protected void setTarget(EObject target) {
			if (enabled) {
				generateID(target);
			}

			super.setTarget(target);
		}

		/**
		 * Generate a new unique ID for an {@code object} based on its containment in its parent object.
		 * 
		 * @param object
		 *            a new object for which to generate a predictable, matchable ID
		 */
		protected void generateID(EObject object) {
			// Everything has a container because we can never attempt to generate
			// the ID of the diagram, itself
			EObject parent = object.eContainer();
			String parentID = resource.getID(parent);
			String newID;

			EReference containment = object.eContainmentFeature();
			int index = indexOf(parent, containment, object);
			if (containment == NotationPackage.Literals.VIEW__PERSISTED_CHILDREN) {
				// For the most common case, the most compact scheme
				newID = format(CHILDREN_PAT, parentID, Integer.valueOf(index));
			} else if (containment == NotationPackage.Literals.VIEW__STYLES) {
				// Identify styles by EClass to avoid ordering issues
				newID = format(STYLES_PAT, parentID, asID(object.eClass().getName()));
			} else {
				newID = format(OTHER_PAT, parentID, asID(containment.getName()), Integer.valueOf(index));
			}

			resource.setID(object, unique(newID));
		}

		/**
		 * Compures the index of an object {@code contained} in some {@code containment} reference of a
		 * {@code container}.
		 * 
		 * @param container
		 *            the containing object
		 * @param containment
		 *            the reference in which the {@code contained} object is stored
		 * @param contained
		 *            the contained object
		 * @return its index
		 */
		protected int indexOf(EObject container, EReference containment, EObject contained) {
			if (containment.isMany()) {
				return ((InternalEList<?>)container.eGet(containment, false)).basicIndexOf(contained);
			} else {
				return 0;
			}
		}

		/**
		 * Transforms a {@link name} from the Ecore model by removing characters that are not valid in an XMI
		 * ID.
		 * 
		 * @param name
		 *            an Ecore name
		 * @return a munged variant that is suitable for concatenation in an XMI ID (usually unchanged)
		 */
		protected String asID(String name) {
			notNCName.reset(name);
			return notNCName.replaceAll(""); //$NON-NLS-1$
		}

		/**
		 * Munge an object identifier, if necessary, to make it unique in the resource.
		 * 
		 * @param id
		 *            an object identifier
		 * @return an unique variant of the identifier (usually unchanged)
		 */
		protected String unique(String id) {
			String base = id;
			String result = base;
			int suffix = -1;

			while (resource.getEObject(result) != null) {
				if (suffix < 0) {
					base = base + '_';
				}
				suffix++;
				result = base + suffix;
			}

			return result;
		}
	}
}
