/*****************************************************************************
 * Copyright (c) 2013, 2017 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:
 *   CEA LIST - Initial API and implementation
 *   Christian W. Damus (CEA) - bug 429242
 *   Christian W. Damus (CEA) - bug 422257
 *   Eike Stepper (CEA) - bug 466520
 *
 *****************************************************************************/
package org.eclipse.papyrus.cdo.internal.core.importer;

import java.util.Collection;
import java.util.Set;

import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.emf.cdo.explorer.CDOExplorerUtil;
import org.eclipse.emf.cdo.explorer.checkouts.CDOCheckout;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.papyrus.cdo.core.importer.IModelImportMapping;
import org.eclipse.papyrus.cdo.core.importer.IModelImporter;
import org.eclipse.papyrus.cdo.core.importer.IModelTransferConfiguration;
import org.eclipse.papyrus.cdo.core.importer.IModelTransferNode;
import org.eclipse.papyrus.cdo.core.importer.IModelTransferOperation;
import org.eclipse.papyrus.cdo.internal.core.Activator;
import org.eclipse.papyrus.cdo.internal.core.CDOUtils;
import org.eclipse.papyrus.cdo.internal.core.controlmode.CDOControlModeParticipant;
import org.eclipse.papyrus.cdo.internal.core.l10n.Messages;
import org.eclipse.papyrus.cdo.internal.core.resource.CDOSashModelProvider;
import org.eclipse.papyrus.infra.core.sashwindows.di.DiPackage;
import org.eclipse.papyrus.infra.core.sashwindows.di.PageList;
import org.eclipse.papyrus.infra.core.sashwindows.di.SashModel;
import org.eclipse.papyrus.infra.core.sashwindows.di.SashWindowsMngr;
import org.eclipse.papyrus.infra.core.sashwindows.di.util.DiUtils;
import org.eclipse.papyrus.infra.emf.utils.EMFHelper;

import com.google.common.collect.Sets;

/**
 * This is the ModelImporter type. Enjoy.
 */
public class ModelImporter implements IModelImporter {

	protected static final ContentType DI_CONTENT = new ContentType("DI"); //$NON-NLS-1$

	protected static final ContentType UML_CONTENT = new ContentType("UML"); //$NON-NLS-1$

	protected static final ContentType NOTATION_CONTENT = new ContentType("Notation"); //$NON-NLS-1$

	protected static final ContentType UNKNOWN_CONTENT = new ContentType("unknown"); //$NON-NLS-1$

	public ModelImporter() {
		super();
	}

	@Override
	public Diagnostic importModels(final IModelImportMapping mapping) {
		BasicDiagnostic result = new BasicDiagnostic();

		add(result, mapping.getConfiguration().validate());
		add(result, mapping.validate());

		if (result.getSeverity() < Diagnostic.ERROR) {
			add(result, mapping.getConfiguration().getOperationContext().run(new IModelTransferOperation() {

				@Override
				public Diagnostic run(IProgressMonitor monitor) {
					return doImport(mapping, monitor);
				}
			}));
		}

		return result;
	}

	protected Diagnostic doImport(IModelImportMapping mapping, IProgressMonitor monitor) {
		BasicDiagnostic result = new BasicDiagnostic();
		IModelTransferConfiguration configuration = mapping.getConfiguration();

		// by the time the configuration has analyzed every model to be
		// imported, all proxies have been resolved that can be. So,
		// there's no need for a further EcoreUtil.resolveAll() or such

		// 1/resource for import and 1/resource for sub-unit proxies
		// 1 for each transaction commit, 1 for saving affected non-imported models, and 1 for clean-up
		SubMonitor sub = SubMonitor.convert(monitor, Messages.ModelImporter_4, configuration.getModelsToTransfer().size() + 4);

		CDOCheckout checkout = mapping.getCheckout();
		CDOTransaction transaction = checkout.openTransaction(new ResourceSetImpl());
		ResourceSet destination = transaction.getResourceSet();

		try {
			for (IModelTransferNode model : configuration.getModelsToTransfer()) {
				add(result, importModel(model, configuration.getResourceSet(), mapping.getMapping(model), transaction, sub.newChild(1)));
			}

			try {
				transaction.commit(sub.newChild(1));

				// save sash resources (if any)
				for (Resource next : destination.getResources()) {
					// sash resource would have been saved by commit if it were a CDO URI
					if (DependencyAdapter.isDIResource(next) && !CDOUtils.isCDOURI(next.getURI())) {
						next.save(null);
					}
				}
			} catch (Exception e) {
				result.add(new BasicDiagnostic(IStatus.ERROR, Activator.PLUGIN_ID, 0, Messages.ModelImporter_5, new Object[] { e }));
			}

			// can't create CDO-style proxies until the resources have been committed, because only then
			// will the objects be persisted and have OIDs to reference
			boolean hasSubUnits = false;
			for (IModelTransferNode model : configuration.getModelsToTransfer()) {
				if (createSubUnitProxies(model, mapping.getMapping(model), transaction, sub.newChild(1))) {
					hasSubUnits = true;
				}
			}
			if (hasSubUnits) {
				try {
					transaction.commit(sub.newChild(1));
				} catch (CommitException e) {
					result.add(new BasicDiagnostic(IStatus.ERROR, Activator.PLUGIN_ID, 0, Messages.ModelImporter_5, new Object[] { e }));
				}
			} else {
				sub.worked(1); // nothing to commit but still count progress
			}

			try {
				saveNonimportedModels(mapping, transaction, sub.newChild(1));
			} catch (Exception e) {
				result.add(new BasicDiagnostic(IStatus.ERROR, Activator.PLUGIN_ID, 0, Messages.ModelImporter_6, new Object[] { e }));
			}
		} finally {
			EMFHelper.unload(configuration.getResourceSet());
			CDOUtils.unload(transaction);
			transaction.close();
			EMFHelper.unload(destination);
			sub.worked(1);
		}

		sub.done();

		return result;
	}

	protected Diagnostic importModel(IModelTransferNode model, ResourceSet rset, IPath toPath, CDOTransaction transaction, IProgressMonitor monitor) {
		BasicDiagnostic result = new BasicDiagnostic();

		IPath basePath = toPath.removeFileExtension();

		SubMonitor sub = SubMonitor.convert(monitor, model.getName(), model.getResourceURIs().size());

		for (URI next : model.getResourceURIs()) {
			Resource destination = transaction.getOrCreateResource(basePath.addFileExtension(next.fileExtension()).toString());
			Resource source = rset.getResource(next, true);

			if (model.getConfiguration().isStripSashModelContent() && DependencyAdapter.isDIResource(source)) {
				// import *.di content into the *.sash
				CDOCheckout checkout = CDOExplorerUtil.getCheckout(transaction);
				URI sashURI = new CDOSashModelProvider().initialize(checkout).getSashModelURI(destination.getURI());
				ResourceSet dset = destination.getResourceSet();
				Resource sashResource = dset.getURIConverter().exists(sashURI, null) ? dset.getResource(sashURI, true) : null;
				if (sashResource == null) {
					sashResource = dset.createResource(sashURI);
				}
				destination = sashResource;
			}

			add(result, importResource(source, destination));
			sub.worked(1);
		}

		sub.done();

		return result;
	}

	protected boolean createSubUnitProxies(IModelTransferNode model, IPath toPath, CDOTransaction transaction, IProgressMonitor monitor) {
		boolean result;

		IPath basePath = toPath.removeFileExtension();
		URI uri = model.getPrimaryResourceURI();

		SubMonitor sub = SubMonitor.convert(monitor, model.getName(), 1);

		Resource destination = transaction.getResource(basePath.addFileExtension(uri.fileExtension()).toString());
		CDOControlModeParticipant.IUpdate update = new CDOControlModeParticipant().getProxyCrossReferencesUpdate(destination);
		result = !update.isEmpty();
		update.apply(); // no harm in applying an empty update
		sub.worked(1);

		sub.done();

		return result;
	}

	protected Diagnostic importResource(Resource source, Resource destination) {
		if (!destination.getContents().isEmpty()) {
			ContentType contentType = getContentType(source);
			if (contentType == DI_CONTENT) {
				mergeDIContent(source, destination);
			} else {
				// just append the additional content
				destination.getContents().addAll(source.getContents());
			}
		} else {
			destination.getContents().addAll(source.getContents());
		}

		return Diagnostic.OK_INSTANCE;
	}

	/**
	 * Determines the content-type of a resource for the purpose of combining
	 * content.
	 *
	 * @param resource
	 *            a resource to be combined with existing content
	 *
	 * @return the content type
	 */
	protected ContentType getContentType(Resource resource) {
		ContentType result = UNKNOWN_CONTENT;

		for (EObject next : resource.getContents()) {
			EPackage ePackage = next.eClass().getEPackage();
			if (ePackage == DiPackage.eINSTANCE) {
				result = DI_CONTENT;
				break;
			}
			if (ePackage.getName().equalsIgnoreCase("uml")) { //$NON-NLS-1$
				result = UML_CONTENT;
				break;
			}
			if (ePackage.getName().equalsIgnoreCase("notation")) { //$NON-NLS-1$
				result = NOTATION_CONTENT;
				break;
			}
		}

		return result;
	}

	protected void mergeDIContent(Resource source, Resource destination) {
		// snip out the source window manager and get its counterpart
		SashWindowsMngr srcMngr = DiUtils.lookupSashWindowsMngr(source);
		EcoreUtil.remove(srcMngr);
		SashWindowsMngr dstMngr = DiUtils.lookupSashWindowsMngr(destination);

		// merge the window manager contents
		if (dstMngr == null) {
			destination.getContents().add(0, srcMngr);
		} else {
			SashModel dstModel = dstMngr.getSashModel();
			SashModel srcModel = srcMngr.getSashModel();

			if (dstModel == null) {
				dstMngr.setSashModel(srcModel);
			} else {
				dstModel.getWindows().addAll(srcModel.getWindows());
				if (dstModel.getCurrentSelection() == null) {
					dstModel.setCurrentSelection(srcModel.getCurrentSelection());
				}
			}

			PageList dstPages = dstMngr.getPageList();
			PageList srcPages = srcMngr.getPageList();

			if (dstPages == null) {
				dstMngr.setPageList(srcPages);
			} else {
				dstPages.getAvailablePage().addAll(srcPages.getAvailablePage());
			}
		}

		// and add all of the tables and other content
		destination.getContents().addAll(source.getContents());
	}

	protected Diagnostic saveNonimportedModels(IModelImportMapping mapping, CDOTransaction transaction, IProgressMonitor monitor) {
		IModelTransferConfiguration configuration = mapping.getConfiguration();

		BasicDiagnostic result = new BasicDiagnostic();

		Collection<IModelTransferNode> imported = configuration.getModelsToTransfer();
		Set<IModelTransferNode> nonImported = Sets.newHashSet();

		for (IModelTransferNode next : configuration.getModelsToTransfer()) {
			for (IModelTransferNode dependent : next.getDependents()) {
				if (!imported.contains(dependent)) {
					nonImported.add(dependent);
				}
			}
		}

		if (!nonImported.isEmpty()) {
			SubMonitor sub = SubMonitor.convert(monitor, Messages.ModelImporter_9, nonImported.size());

			ResourceSet rset = configuration.getResourceSet();

			try {
				for (IModelTransferNode next : nonImported) {
					for (URI uri : next.getResourceURIs()) {
						Resource resource = rset.getResource(uri, false);

						// if the resource is modified, then we imported it, so
						// don't save
						if ((resource != null) && !resource.isModified()) {
							try {
								resource.save(null);
							} catch (Exception e) {
								add(result, new BasicDiagnostic(IStatus.ERROR, Activator.PLUGIN_ID, 0, Messages.ModelImporter_10, new Object[] { e }));
							}
						}
					}

					sub.worked(1);
				}
			} finally {
				sub.done();
			}
		}

		return result;
	}

	private static void add(DiagnosticChain diagnostics, Diagnostic diagnostic) {
		if (diagnostic.getSeverity() > Diagnostic.OK) {
			diagnostics.merge(diagnostic);
		}
	}

	//
	// Nested types
	//

	protected static class ContentType {

		private final String name;

		protected ContentType(String name) {
			this.name = name;
		}

		public final String getName() {
			return name;
		}

		@Override
		public int hashCode() {
			return getName().hashCode();
		}

		@Override
		public boolean equals(Object obj) {
			return (obj instanceof ContentType) && ((ContentType) obj).getName().equals(getName());
		}

		@Override
		public String toString() {
			return getName() + " content"; //$NON-NLS-1$
		}
	}
}
