/*******************************************************************************
 * Copyright (c) 2011, 2019 Mia-Software and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v20.html
 *
 * Contributors:
 *    Hugues Dubourg (Mia-Software) - initial API and implementation
 *    Gabriel Barbier (Mia-Software) - initial API and implementation
 *    Nicolas Bros (Mia-Software) - Bug 335003 - [Discoverer] : Existing Discoverers Refactoring based on new framework
 *******************************************************************************/

package org.eclipse.modisco.kdm.uml2converter.internal;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.IJobChangeEvent;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.core.runtime.jobs.JobChangeAdapter;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.m2m.atl.common.ATLLaunchConstants;
import org.eclipse.m2m.atl.core.ATLCoreException;
import org.eclipse.m2m.atl.core.IExtractor;
import org.eclipse.m2m.atl.core.IInjector;
import org.eclipse.m2m.atl.core.IModel;
import org.eclipse.m2m.atl.core.IReferenceModel;
import org.eclipse.m2m.atl.core.ModelFactory;
import org.eclipse.m2m.atl.core.emf.EMFModel;
import org.eclipse.m2m.atl.core.launch.ILauncher;
import org.eclipse.m2m.atl.core.service.CoreService;
import org.eclipse.m2m.atl.engine.parser.AtlParser;
import org.eclipse.modisco.infra.common.core.logging.MoDiscoLogger;
import org.eclipse.modisco.util.atl.core.internal.AtlLaunchHelper;
import org.eclipse.modisco.util.atl.core.internal.AtlLaunchHelper.ModelInfo;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.uml2.uml.internal.impl.UMLPackageImpl;

/**
 * @deprecated See Bug 559506- the KDMtoUML transformation has not been revised for UML2 5.0.0.
 */
@Deprecated
public class KdmToUmlConverter {

	public static final String MM_LOCATION = "resources/metamodels"; //$NON-NLS-1$
	public static final String TRANSFO_LOCATION = "resources/transformations"; //$NON-NLS-1$
	public static final String KDM_MM_URI = org.eclipse.modisco.omg.kdm.action.ActionPackage.eNS_URI;
	public static final String UML_MM_URI = UMLPackageImpl.eNS_URI; //$NON-NLS-1$
	private static final String ATL_MM_PATH = "http://www.eclipse.org/gmt/2005/ATL"; //$NON-NLS-1$

	public Resource[] getUML2ModelFromKDMModel(final Resource kdmModel, final boolean generateTraces)
			throws IOException, ATLCoreException {
		URL transformation;
		Resource[] result = null;
		if (generateTraces) {
			transformation = this.getClass().getResource(
					KdmToUmlConverter.TRANSFO_LOCATION + "/KDMtoUMLWithTraces.asm"); //$NON-NLS-1$
			result = getUML2ModelFromKDMModelWithCustomTransformation(kdmModel, generateTraces,
					transformation);
		} else {
			transformation = this.getClass().getResource(
					KdmToUmlConverter.TRANSFO_LOCATION + "/KDMtoUML.asm"); //$NON-NLS-1$
			result = getUML2ModelFromKDMModelWithCustomTransformation(kdmModel, generateTraces,
					transformation);
		}

		return result;
	}

	public Resource[] getUML2ModelFromKDMModelWithCustomTransformation(
			final Resource kdmSourceModel, final boolean generateTraces, final URL transformation)
			throws IOException, ATLCoreException {

		final List<ModelInfo> inputModels = new ArrayList<ModelInfo>();
		final List<ModelInfo> outputModels = new ArrayList<ModelInfo>();

		URI umlTargetModelUri = URI.createURI("memory:/umlTargetModel"); //$NON-NLS-1$

		final ModelInfo inputModel = new ModelInfo(
				"kdmInput", kdmSourceModel.getURI(), kdmSourceModel, "kdm", //$NON-NLS-1$ //$NON-NLS-2$
				URI.createURI(KdmToUmlConverter.KDM_MM_URI));
		inputModels.add(inputModel);
		final ModelInfo outputModel = new ModelInfo(
				"umlOutput", umlTargetModelUri, kdmSourceModel, "uml", //$NON-NLS-1$ //$NON-NLS-2$
				URI.createURI(KdmToUmlConverter.UML_MM_URI));
		outputModels.add(outputModel);

		if (generateTraces) {
			final URL mmwMMURL = this.getClass().getResource(
					KdmToUmlConverter.MM_LOCATION + "/mmw_traceability.ecore"); //$NON-NLS-1$
			final ModelInfo traceModel = new ModelInfo("trace", umlTargetModelUri //$NON-NLS-1$
					.trimFileExtension().appendFileExtension("trace.amw"), null, "Trace", //$NON-NLS-1$ //$NON-NLS-2$
					URI.createURI(mmwMMURL.toString()));
			outputModels.add(traceModel);
		}

		AtlLaunchHelper atlHelper = new AtlLaunchHelper();
		List<Resource> results = atlHelper.runTransformation(transformation, inputModels,
				outputModels);

		Resource[] resultsArray = new Resource[results.size()];
		results.toArray(resultsArray);
		return resultsArray;
	}

	public final void basicExportKdmToUmlTransformation(final IFile file,
			final IProgressMonitor monitor) throws CoreException {
		final InputStream transfoFileStream = this.getClass().getResourceAsStream(
				KdmToUmlConverter.TRANSFO_LOCATION + "/KDMtoUML.atl"); //$NON-NLS-1$
		if (file.exists()) {
			file.setContents(transfoFileStream, IResource.FORCE, monitor);
		} else {
			file.create(transfoFileStream, IResource.FORCE, monitor);
		}
	}

	public void exportKdmToUmlTransformation(final IPath pathParameter) {
		IPath path = pathParameter;
		if (path.getFileExtension() == null || !path.getFileExtension().equals("atl")) { //$NON-NLS-1$
			path = path.addFileExtension("atl"); //$NON-NLS-1$
		}
		final IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
		final IProject destinationProject = file.getProject();
		Job job = new Job(Messages.KDMtoUML2Converter_27) {
			@Override
			protected IStatus run(final IProgressMonitor monitor) {
				try {
					basicExportKdmToUmlTransformation(file, monitor);
				} catch (CoreException e) {
					return Status.CANCEL_STATUS;
				}
				return Status.OK_STATUS;
			}
		};
		// when copy job is done, open the file
		job.addJobChangeListener(new JobChangeAdapter() {
			@Override
			public void done(final IJobChangeEvent event) {
				Display.getDefault().asyncExec(new Runnable() {
					public void run() {
						try {
							destinationProject.refreshLocal(IResource.DEPTH_INFINITE,
									new NullProgressMonitor());
							IWorkbenchPage page = PlatformUI.getWorkbench()
									.getActiveWorkbenchWindow().getActivePage();
							IDE.openEditor(page, file);
						} catch (Exception e) {
							MoDiscoLogger.logError(e, KdmToUml2Activator.getDefault());
						}
					}
				});
			}
		});
		job.schedule();
	}

	public IFile instrumentAtlTranformationWithTraceability(final InputStream sourceTransformation,
			final URI atlFileUri) throws ATLCoreException {
		URI sourceModelUri = atlFileUri.trimFileExtension()
				.appendFragment("-ATL_source").appendFileExtension("ecore"); //$NON-NLS-1$ //$NON-NLS-2$
		URI targetModelUri = atlFileUri.trimFileExtension()
				.appendFragment("-ATL_target").appendFileExtension("ecore"); //$NON-NLS-1$ //$NON-NLS-2$

		// transforms ATL file into ATL model
		IModel sourceModel = AtlParser.getDefault().parseToModel(sourceTransformation);
		if (sourceModel instanceof EMFModel) {
			EMFModel ecoreSourceModel = (EMFModel) sourceModel;
			try {
				ecoreSourceModel.getResource().setURI(sourceModelUri);
				ecoreSourceModel.getResource().save(null);
			} catch (IOException e) {
				MoDiscoLogger.logError(e, KdmToUml2Activator.getDefault());
			}
		}

		IModel targetModel = addTraceability(sourceModel, sourceModelUri, targetModelUri);

		if (targetModel instanceof EMFModel) {
			EMFModel ecoreTargetModel = (EMFModel) targetModel;
			try {
				ecoreTargetModel.getResource().setURI(targetModelUri);
				ecoreTargetModel.getResource().save(null);
			} catch (IOException e) {
				MoDiscoLogger.logError(e, KdmToUml2Activator.getDefault());
			}

		}
		IFile result = null;
		// transforms ATL model into ATL file
		try {
			result = parseFromModel(targetModel, atlFileUri);
		} catch (IOException e) {
			MoDiscoLogger.logError(e, KdmToUml2Activator.getDefault());
		}

		return result;
	}

	public final IModel addTraceability(final IModel sourceModel, final URI sourceModelUri,
			final URI targetModelUri) throws ATLCoreException {
		final URL transformation = this.getClass().getResource(
				KdmToUmlConverter.TRANSFO_LOCATION + "/ATL2WTracer.asm"); //$NON-NLS-1$

		Map<String, String> modelHandlers = new HashMap<String, String>();
		String atlMetaModelName = "ATL"; //$NON-NLS-1$
		modelHandlers.put(atlMetaModelName, "EMF"); //$NON-NLS-1$

		final Map<String, Object> options = new HashMap<String, Object>();
		options.put(ATLLaunchConstants.OPTION_MODEL_HANDLER, modelHandlers);
		options.put(ATLLaunchConstants.IS_REFINING, true);

		String launcherName = ATLLaunchConstants.EMF_VM_NAME;
		final ILauncher launcher = CoreService.getLauncher(launcherName);
		launcher.initialize(options);

		ModelFactory factory = CoreService.getModelFactory(launcher.getDefaultModelFactoryName());

		IInjector injector = CoreService.getInjector(factory.getDefaultInjectorName());
		IExtractor extractor = CoreService.getExtractor(factory.getDefaultExtractorName());

		// load meta model ATL
		IReferenceModel atlMM = factory.getBuiltInResource("ATL.ecore"); //$NON-NLS-1$
		// load model source
		Map<String, Object> modelOptions = new HashMap<String, Object>();
		String inModelName = "IN"; //$NON-NLS-1$
		modelOptions.put("modelName", inModelName); //$NON-NLS-1$
		modelOptions.put("path", sourceModelUri.toString()); //$NON-NLS-1$
		modelOptions.put("newModel", false); //$NON-NLS-1$
		IModel input = factory.newModel(atlMM, modelOptions);
		injector.inject(input, sourceModelUri.toString());
		launcher.addInModel(input, inModelName, atlMetaModelName);
		// load model cible
		modelOptions = new HashMap<String, Object>();
		inModelName = "OUT"; //$NON-NLS-1$
		modelOptions.put("modelName", inModelName); //$NON-NLS-1$
		modelOptions.put("path", targetModelUri.toString()); //$NON-NLS-1$
		modelOptions.put("newModel", true); //$NON-NLS-1$
		IModel outputInstance = factory.newModel(atlMM, modelOptions);
		launcher.addOutModel(outputInstance, inModelName, atlMetaModelName);

		/*
		 * Encapsulate ATL transformation into a new Thread to reset the Stack (avoid stack
		 * overflow)
		 */
		options.put("continueAfterError", "true"); //$NON-NLS-1$ //$NON-NLS-2$
		options.put("printExecutionTime", "true"); //$NON-NLS-1$ //$NON-NLS-2$

		Job transformationThread = new Job(Messages.KDMtoUML2Converter_42) {
			@Override
			protected IStatus run(final IProgressMonitor monitor) {
				IStatus result = Status.OK_STATUS;
				try {
					launcher.launch(ILauncher.RUN_MODE, monitor, options,
							transformation.openStream());
				} catch (IOException e) {
					result = Status.CANCEL_STATUS;
					MoDiscoLogger.logError(e, KdmToUml2Activator.getDefault());
				}

				return result;
			}
		};
		transformationThread.schedule();
		try {
			transformationThread.join();
		} catch (InterruptedException e) {
			MoDiscoLogger.logError(e, KdmToUml2Activator.getDefault());
		}

		extractor.extract(outputInstance, targetModelUri.toString());

		return outputInstance;
	}

	public static final IFile parseFromModel(final IModel transformationModel, final URI atlFileUri)
			throws IOException {
		IFile file = null;
		IPath atlFilePath = null;
		if (atlFileUri.isPlatformResource()) {
			atlFilePath = new Path(atlFileUri.toPlatformString(false));
			file = ResourcesPlugin.getWorkspace().getRoot().getFile(atlFilePath);
		} else {
			atlFilePath = new Path(atlFileUri.toFileString());
			file = ResourcesPlugin.getWorkspace().getRoot().getFileForLocation(atlFilePath);
		}
		if (file != null) {
			try {
				AtlParser.getDefault().extract(transformationModel, file.getLocation().toString());
			} catch (Exception e) {
				MoDiscoLogger.logError(e, KdmToUml2Activator.getDefault());
			}
			try {
				file.refreshLocal(0, new NullProgressMonitor());
			} catch (CoreException e) {
				MoDiscoLogger.logError(e, KdmToUml2Activator.getDefault());
			}
		} else {
			MoDiscoLogger.logError("Uri invalid", KdmToUml2Activator.getDefault()); //$NON-NLS-1$
		}
		return file;
	}
}
