/*******************************************************************************
 * Copyright (c) 2010, 2017 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
 * Dmitry Spiridenok <d.spiridenok@gmail.com> - Bug 408712
 * Marco Descher <marco@descher.at> - Bug 434371
 * Olivier Prouvost <olivier.prouvost@opcoach.com> Bug 485723, Bug 436836
 ******************************************************************************/
package org.eclipse.e4.internal.tools.wizards.model;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.e4.internal.tools.Messages;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
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.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.wizard.Wizard;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.eclipse.pde.core.build.IBuildEntry;
import org.eclipse.pde.core.plugin.IExtensionsModelFactory;
import org.eclipse.pde.core.plugin.IMatchRules;
import org.eclipse.pde.core.plugin.IPluginAttribute;
import org.eclipse.pde.core.plugin.IPluginElement;
import org.eclipse.pde.core.plugin.IPluginExtension;
import org.eclipse.pde.core.plugin.IPluginExtensionPoint;
import org.eclipse.pde.core.plugin.IPluginImport;
import org.eclipse.pde.core.plugin.IPluginModelBase;
import org.eclipse.pde.core.plugin.IPluginObject;
import org.eclipse.pde.core.plugin.PluginRegistry;
import org.eclipse.pde.internal.core.build.WorkspaceBuildModel;
import org.eclipse.pde.internal.core.bundle.BundlePluginModel;
import org.eclipse.pde.internal.core.bundle.WorkspaceBundlePluginModel;
import org.eclipse.pde.internal.core.project.PDEProject;
import org.eclipse.ui.INewWizard;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.IWorkbenchWizard;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.actions.WorkspaceModifyOperation;
import org.eclipse.ui.part.FileEditorInput;
import org.eclipse.ui.part.ISetSelectionTarget;

@SuppressWarnings("restriction")
public abstract class BaseApplicationModelWizard extends Wizard implements INewWizard {
	private NewModelFilePage page;
	private ISelection selection;

	protected IWorkbench workbench;

	/**
	 * Constructor for NewApplicationModelWizard.
	 */
	public BaseApplicationModelWizard() {
		super();
		setNeedsProgressMonitor(true);
	}

	/**
	 * Adding the page to the wizard.
	 */

	@Override
	public void addPages() {
		page = createWizardPage(selection);
		addPage(page);
	}

	protected abstract NewModelFilePage createWizardPage(ISelection selection);

	public abstract String getDefaultFileName();

	@Override
	public boolean performFinish() {
		try {
			// Remember the file.
			//
			final IFile modelFile = getModelFile();

			if (modelFile.exists()) {
				final boolean continueWithExistingFile = handleFileExist();
				if (!continueWithExistingFile) {
					return true;
				}

			}

			// Do the work within an operation.
			//
			final WorkspaceModifyOperation operation = new WorkspaceModifyOperation() {
				@Override
				protected void execute(IProgressMonitor progressMonitor) {
					try {
						// Create a resource set
						//
						final ResourceSet resourceSet = new ResourceSetImpl();

						// Get the URI of the model file.
						//
						final URI fileURI = URI.createPlatformResourceURI(modelFile.getFullPath().toString(), true);

						// Create a resource for this file.
						//
						final Resource resource = resourceSet.createResource(fileURI);

						final EObject rootObject = createInitialModel();

						if (rootObject == null) {
							throw new IllegalArgumentException(Messages.BaseApplicationModelWizard_ModelRootMustNotBeNull);
						}

						// If target file already exists, load its content
						//
						if (modelFile.exists()) {
							resource.load(null);

							mergeWithExistingFile(resource, rootObject);
						} else {
							// If target model is empty (file just created)
							// => add as is
							resource.getContents().add(rootObject);
						}

						// Save the contents of the resource to the file system.
						//
						final Map<Object, Object> options = new HashMap<>();
						resource.save(options);
						adjustBuildPropertiesFile(modelFile);
						adjustDependencies(modelFile);
					} catch (final Exception exception) {
						throw new RuntimeException(exception);
					} finally {
						progressMonitor.done();
					}
				}
			};

			getContainer().run(false, false, operation);

			// Select the new file resource in the current view.
			//
			final IWorkbenchWindow workbenchWindow = workbench.getActiveWorkbenchWindow();
			final IWorkbenchPage page = workbenchWindow.getActivePage();
			final IWorkbenchPart activePart = page.getActivePart();
			if (activePart instanceof ISetSelectionTarget) {
				final ISelection targetSelection = new StructuredSelection(modelFile);
				getShell().getDisplay()
				.asyncExec(() -> ((ISetSelectionTarget) activePart).selectReveal(targetSelection));
			}

			// Open an editor on the new file.
			//
			try {
				page.openEditor(new FileEditorInput(modelFile),
						workbench.getEditorRegistry().getDefaultEditor(modelFile.getFullPath().toString()).getId());
			} catch (final PartInitException exception) {
				MessageDialog.openError(workbenchWindow.getShell(), "Could not init editor", exception.getMessage()); //$NON-NLS-1$
				return false;
			}

			return true;
		} catch (final Exception exception) {
			exception.printStackTrace();
			MessageDialog.openError(getShell(), Messages.BaseApplicationModelWizard_Error, exception.getMessage());
			return false;
		}
	}

	/**
	 * @return if the wizard should continue in case the file already exists
	 */
	protected boolean handleFileExist() {
		MessageDialog.openInformation(getShell(), Messages.BaseApplicationModelWizard_FileExists,
				Messages.BaseApplicationModelWizard_TheFileAlreadyExists);

		return false;
	}

	/**
	 * Creates the rootObject of the new model file. Must not be null.
	 *
	 * @return The root {@link EObject}
	 */
	protected abstract EObject createInitialModel();

	protected IFile getModelFile() throws CoreException {
		final String containerName = page.getContainerName();
		final String fileName = page.getFileName();
		final IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
		final IResource resource = root.findMember(new Path(containerName));
		if (!resource.exists() || !(resource instanceof IContainer)) {
			throwCoreException("Container \"" + containerName //$NON-NLS-1$
					+ "\" does not exist."); //$NON-NLS-1$
		}
		final IContainer container = (IContainer) resource;
		return container.getFile(new Path(fileName));
	}

	private void throwCoreException(String message) throws CoreException {
		final IStatus status = new Status(IStatus.ERROR, "org.eclipse.e4.tools.emf.editor3x", IStatus.OK, message, //$NON-NLS-1$
				null);
		throw new CoreException(status);
	}

	/**
	 * We will accept the selection in the workbench to see if we can initialize
	 * from it.
	 *
	 * @see IWorkbenchWizard#init(IWorkbench, IStructuredSelection)
	 */
	@Override
	public void init(IWorkbench workbench, IStructuredSelection selection) {
		this.workbench = workbench;
		this.selection = selection;
	}

	/**
	 * Adds other file to the build.properties file.
	 */
	private void adjustBuildPropertiesFile(IFile file) throws CoreException {
		final IProject project = file.getProject();
		final IFile buildPropertiesFile = PDEProject.getBuildProperties(project);
		if (buildPropertiesFile.exists()) {
			final WorkspaceBuildModel model = new WorkspaceBuildModel(buildPropertiesFile);
			final IBuildEntry entry = model.getBuild().getEntry(IBuildEntry.BIN_INCLUDES);
			final String token = file.getProjectRelativePath().toString();
			if (!entry.contains(token)) {
				entry.addToken(token);
			}
			model.save();
		}
	}

	/**
	 * Callback hook to allow for after-file-creation modifications. Default
	 * implementation does nothing.
	 *
	 * @param file
	 *            the file created by the wizard
	 */
	protected void adjustDependencies(IFile file) {
	}

	/**
	 * Add the required dependencies (org.eclipse.e4.ui.model.workbench) and
	 * register fragment.e4xmi at the required extension point
	 * (org.eclipse.e4.workbench.model)
	 */
	protected void adjustFragmentDependencies(IFile file) {
		final IProject project = file.getProject();
		final IFile pluginXml = PDEProject.getPluginXml(project);
		final IFile manifest = PDEProject.getManifest(project);

		final WorkspaceBundlePluginModel fModel = new WorkspaceBundlePluginModel(manifest, pluginXml);
		try {
			addWorkbenchDependencyIfRequired(fModel);
			registerWithExtensionPointIfRequired(project, fModel, file);
		} catch (final CoreException e) {
			e.printStackTrace();
			MessageDialog.openError(getShell(), Messages.BaseApplicationModelWizard_Error, e.getMessage());
		}
	}

	private void addWorkbenchDependencyIfRequired(WorkspaceBundlePluginModel fModel) throws CoreException {
		final IPluginImport[] imports = fModel.getPluginBase().getImports();

		final String WORKBENCH_IMPORT_ID = "org.eclipse.e4.ui.model.workbench"; //$NON-NLS-1$

		for (final IPluginImport iPluginImport : imports) {
			if (WORKBENCH_IMPORT_ID.equalsIgnoreCase(iPluginImport.getId())) {
				return;
			}
		}

		String version = ""; //$NON-NLS-1$
		final IPluginModelBase findModel = PluginRegistry.findModel(WORKBENCH_IMPORT_ID);
		if (findModel != null) {
			final BundleDescription bundleDescription = findModel.getBundleDescription();
			if (bundleDescription != null) {
				version = bundleDescription.getVersion().toString().replaceFirst("\\.qualifier$", ""); //$NON-NLS-1$ //$NON-NLS-2$
			}
		}

		final IPluginImport workbenchImport = fModel.getPluginFactory().createImport();
		workbenchImport.setId(WORKBENCH_IMPORT_ID);
		workbenchImport.setVersion(version);
		workbenchImport.setMatch(IMatchRules.GREATER_OR_EQUAL);
		fModel.getPluginBase().add(workbenchImport);
		fModel.save();
	}

	/**
	 * Register the fragment.e4xmi with the org.eclipse.e4.workbench.model
	 * extension point, if there is not already a fragment registered.
	 */
	private void registerWithExtensionPointIfRequired(IProject project, WorkspaceBundlePluginModel fModel, IFile file)
			throws CoreException {

		final String WORKBENCH_MODEL_EP_ID = "org.eclipse.e4.workbench.model"; //$NON-NLS-1$
		final String FRAGMENT = "fragment"; //$NON-NLS-1$

		// Fix bug #436836 : the received fModel is an empty plugin model
		// without extension.
		// We must copy extensions found in registry plugin model into it
		// The registry plugin model is read only and must be copied inside the
		// new extension value..
		final BundlePluginModel registryModel = (BundlePluginModel) PluginRegistry.findModel(project.getName());
		// The registry Model is not modifiable and may be contains some
		// existing extensions.
		// Must copy them in the new created fModel
		for (final IPluginExtension e : registryModel.getPluginBase().getExtensions()) {
			final IPluginExtension clonedExtens = copyExtension(fModel.getFactory(), e);
			fModel.getPluginBase().add(clonedExtens);
		}

		// Fix 485723 Must do the same for extension points
		for (final IPluginExtensionPoint ep : registryModel.getPluginBase().getExtensionPoints()) {
			final IPluginExtensionPoint clonedExtensionPoint = copyExtensionPoint(fModel.getFactory(), ep);
			fModel.getPluginBase().add(clonedExtensionPoint);
		}

		// Can now check if we must add this extension (may be already inside).
		final IPluginExtension[] extensions = fModel.getPluginBase().getExtensions();
		for (final IPluginExtension iPluginExtension : extensions) {
			if (WORKBENCH_MODEL_EP_ID.equalsIgnoreCase(iPluginExtension.getPoint())) {
				final IPluginObject[] children = iPluginExtension.getChildren();
				for (final IPluginObject child : children) {
					if (FRAGMENT.equalsIgnoreCase(child.getName())) {
						return;
					}
				}
			}
		}

		final IPluginExtension extPointFragmentRegister = fModel.getPluginFactory().createExtension();
		final IPluginElement element = extPointFragmentRegister.getModel().getFactory()
				.createElement(extPointFragmentRegister);
		element.setName(FRAGMENT);
		element.setAttribute("uri", file.getName()); //$NON-NLS-1$
		extPointFragmentRegister.setId(project.getName() + "." + FRAGMENT); //$NON-NLS-1$
		extPointFragmentRegister.setPoint(WORKBENCH_MODEL_EP_ID);
		extPointFragmentRegister.add(element);
		fModel.getPluginBase().add(extPointFragmentRegister);
		fModel.save();
	}

	// Used to Fix bug #436836
	private IPluginExtension copyExtension(IExtensionsModelFactory factory, final IPluginExtension ext) {
		try {
			final IPluginExtension clonedExt = factory.createExtension();
			clonedExt.setPoint(ext.getPoint());
			final IPluginObject[] _children = ext.getChildren();
			for (final IPluginObject elt : _children) {
				if (elt instanceof IPluginElement) {
					final IPluginElement ipe = (IPluginElement) elt;
					final IPluginElement clonedElt = copyExtensionElement(factory, ipe, ext);
					clonedExt.add(clonedElt);
				}
			}
			return clonedExt;
		} catch (final Exception e) {
			e.printStackTrace();
		}
		return null;

	}

	// Used to Fix bug #485723
	private IPluginExtensionPoint copyExtensionPoint(IExtensionsModelFactory factory, final IPluginExtensionPoint ep) {
		try {
			final IPluginExtensionPoint clonedExtPt = factory.createExtensionPoint();
			clonedExtPt.setId(ep.getId());
			clonedExtPt.setName(ep.getName());
			clonedExtPt.setSchema(ep.getSchema());

			return clonedExtPt;
		} catch (final Exception e) {
			e.printStackTrace();
		}
		return null;

	}

	// Used to Fix bug #436836
	private IPluginElement copyExtensionElement(IExtensionsModelFactory factory, final IPluginElement elt,
			final IPluginObject parent) {
		try {
			final IPluginElement clonedElt = factory.createElement(parent);
			clonedElt.setName(elt.getName());
			for (final IPluginAttribute a : elt.getAttributes()) {
				clonedElt.setAttribute(a.getName(), a.getValue());
			}
			for (final IPluginObject e : elt.getChildren()) {
				if (e instanceof IPluginElement) {
					final IPluginElement ipe = (IPluginElement) e;
					final IPluginElement copyExtensionElement = copyExtensionElement(factory, ipe, clonedElt);
					clonedElt.add(copyExtensionElement);
				}
			}
			return clonedElt;
		} catch (final Exception e) {
			e.printStackTrace();
		}
		return null;

	}

	/**
	 * @param resource
	 * @param rootObject
	 */
	protected void mergeWithExistingFile(Resource resource, EObject rootObject) {
		// do nothing

	}

}