/*******************************************************************************
 * Copyright (c) 2011-2012 EclipseSource Muenchen GmbH 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:
 * Eugen Neufeld - initial API and implementation
 *
 *******************************************************************************/

package org.eclipse.emf.ecp.spi.ui.util;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecp.core.ECPProject;
import org.eclipse.emf.ecp.core.ECPProjectManager;
import org.eclipse.emf.ecp.core.ECPProvider;
import org.eclipse.emf.ecp.core.ECPRepository;
import org.eclipse.emf.ecp.core.exceptions.ECPProjectWithNameExistsException;
import org.eclipse.emf.ecp.core.util.ECPCheckoutSource;
import org.eclipse.emf.ecp.core.util.ECPContainer;
import org.eclipse.emf.ecp.core.util.ECPProperties;
import org.eclipse.emf.ecp.core.util.ECPUtil;
import org.eclipse.emf.ecp.internal.ui.Activator;
import org.eclipse.emf.ecp.internal.ui.Messages;
import org.eclipse.emf.ecp.internal.ui.dialogs.DeleteDialog;
import org.eclipse.emf.ecp.internal.ui.dialogs.ProjectPropertiesDialog;
import org.eclipse.emf.ecp.internal.ui.dialogs.RepositoryPropertiesDialog;
import org.eclipse.emf.ecp.internal.ui.util.HandlerHelperUtil;
import org.eclipse.emf.ecp.internal.wizards.AddRepositoryWizard;
import org.eclipse.emf.ecp.internal.wizards.CheckoutProjectWizard;
import org.eclipse.emf.ecp.internal.wizards.CreateProjectWizard;
import org.eclipse.emf.ecp.internal.wizards.FilterModelElementWizard;
import org.eclipse.emf.ecp.spi.common.ui.CheckedModelClassComposite;
import org.eclipse.emf.ecp.spi.common.ui.SelectModelElementWizard;
import org.eclipse.emf.ecp.spi.common.ui.composites.SelectionComposite;
import org.eclipse.emf.ecp.spi.core.InternalProject;
import org.eclipse.emf.ecp.spi.core.InternalProvider;
import org.eclipse.emf.ecp.spi.core.InternalProvider.LifecycleEvent;
import org.eclipse.emf.ecp.ui.common.AddRepositoryComposite;
import org.eclipse.emf.ecp.ui.common.CheckoutProjectComposite;
import org.eclipse.emf.ecp.ui.common.CreateProjectComposite;
import org.eclipse.emf.ecp.ui.common.ECPCompositeFactory;
import org.eclipse.emf.ecp.ui.util.ECPModelElementOpenTester;
import org.eclipse.emf.ecp.ui.util.ECPModelElementOpener;
import org.eclipse.emf.ecp.ui.util.ECPModelElementOpenerWithContext;
import org.eclipse.emf.edit.command.ChangeCommand;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.dialogs.ListSelectionDialog;

/**
 * This is a utility class providing commonly necessary methods.
 *
 * @author Eugen Neufeld
 * @since 1.4
 */
public final class ECPHandlerHelper {
	private ECPHandlerHelper() {
	}

	private static void showError(Shell shell, String title, String message) {
		MessageDialog.openError(shell, title, message);
	}

	/**
	 * This method allows to checkout a list of {@link ECPCheckoutSource} into the workspace.
	 *
	 * @param checkoutObjects the List of {@link ECPCheckoutSource} to checkout
	 * @param shell the {@link Shell} to use for diplaying UI
	 */
	public static void checkout(final List<ECPCheckoutSource> checkoutObjects, final Shell shell) {
		for (final ECPCheckoutSource checkoutSource : checkoutObjects) {
			final CheckoutProjectComposite checkoutCompposite = ECPCompositeFactory
				.getCheckoutProjectComposite(checkoutSource);
			final CheckoutProjectWizard wizard = new CheckoutProjectWizard();
			wizard.setCompositeProvider(checkoutCompposite);

			final WizardDialog wd = new WizardDialog(shell, wizard);

			final int result = wd.open();
			if (result == Window.OK) {

				final String projectName = checkoutCompposite.getProjectName();
				final ECPProperties projectProperties = checkoutCompposite.getProjectProperties();
				try {
					checkoutSource.checkout(projectName, projectProperties);
				} catch (final ECPProjectWithNameExistsException ex) {
					showError(shell, "Cannot checkout project", "A project with name " + projectName //$NON-NLS-1$ //$NON-NLS-2$
						+ " already exists in the workspace."); //$NON-NLS-1$
				}
			}
		}
	}

	/**
	 * This helper method is used to delete model elements from a project.
	 *
	 * @param project the project to delete from
	 * @param objects the model elements to delete
	 */
	public static void deleteModelElement(final ECPProject project, final Collection<Object> objects) {
		if (project != null) {
			project.deleteElements(objects);
		}
	}

	/**
	 * This method creates a new project.
	 *
	 * @param shell the shell for displaying the wizard
	 * @return the created {@link ECPProject}
	 */
	public static ECPProject createProject(final Shell shell) {
		final List<ECPProvider> providers = new ArrayList<ECPProvider>();
		for (final ECPProvider provider : ECPUtil.getECPProviderRegistry().getProviders()) {
			if (provider.hasCreateProjectWithoutRepositorySupport()) {
				providers.add(provider);
			}
		}
		if (providers.size() == 0) {
			// TODO language
			showError(shell, "No Provider", "Please check if a suitable provider is installed."); //$NON-NLS-1$//$NON-NLS-2$
			return null;
		}
		final CreateProjectComposite createProjectComposite = ECPCompositeFactory.getCreateProjectComposite(providers);
		final CreateProjectWizard wizard = new CreateProjectWizard();
		wizard.setCompositeProvider(createProjectComposite);

		final WizardDialog wd = new WizardDialog(shell, wizard);

		final int result = wd.open();
		if (result == Window.OK) {
			final ECPProvider selectedProvider = createProjectComposite.getProvider();
			if (selectedProvider == null) {
				showError(shell, "No project created", "Please check if a suitable provider is installed."); //$NON-NLS-1$//$NON-NLS-2$
				return null;
			}

			final ECPProperties projectProperties = createProjectComposite.getProperties();
			final String projectName = createProjectComposite.getProjectName();

			ECPProject project = null;
			try {
				project = ECPUtil.getECPProjectManager()
					.createProject(selectedProvider, projectName, projectProperties);
			} catch (final ECPProjectWithNameExistsException ex) {
				showError(shell, "No project created", "A project with name " + projectName //$NON-NLS-1$ //$NON-NLS-2$
					+ " already exists in the workspace."); //$NON-NLS-1$
				return null;
			}
			if (project == null) {
				showError(shell, "No project created", "Please check the log."); //$NON-NLS-1$//$NON-NLS-2$
				return null;
			}
			((InternalProvider) selectedProvider).handleLifecycle(project, LifecycleEvent.CREATE);
			project.open();
			return project;
		}
		return null;
	}

	/**
	 * Add a new {@link EObject} to the root of an {@link ECPProject}.
	 *
	 * @param ecpProject the {@link ECPProject} to add the {@link EObject} to
	 * @param shell the {@link Shell} used to display the UI
	 * @param open whether to open the corresponding editor or not
	 * @return the created {@link EObject}
	 */
	public static EObject addModelElement(final ECPProject ecpProject, final Shell shell, boolean open) {
		final EClass newMEType = openSelectModelElementWizard(ecpProject, shell, open);
		if (ecpProject != null && newMEType != null) {
			// create ME
			final EObject newMEInstance = createModelElementInstance(newMEType);
			ecpProject.getEditingDomain().getCommandStack().execute(new ChangeCommand(newMEInstance) {

				@Override
				protected void doExecute() {
					ecpProject.getContents().add(newMEInstance);
				}
			});
			if (open) {
				openModelElement(newMEInstance, ecpProject);
			}
			return newMEInstance;
		}
		return null;
	}

	/**
	 * @param resource the resource
	 * @param activeShell current active shell
	 * @param open if model element should be directly opened in an editor after it is added to project.
	 *
	 * @return the created model element.
	 */
	public static EObject addModelElement(final Resource resource, Shell activeShell, boolean open) {

		final ECPProject ecpProject = ECPUtil.getECPProjectManager().getProject(resource);
		if (ecpProject == null) {
			return null;
		}
		final EClass newMEType = openSelectModelElementWizard(ecpProject, activeShell, open);
		if (resource != null && newMEType != null) {
			// create ME
			final EObject newMEInstance = createModelElementInstance(newMEType);
			ecpProject.getEditingDomain().getCommandStack().execute(new ChangeCommand(newMEInstance) {

				@Override
				protected void doExecute() {
					resource.getContents().add(newMEInstance);
				}
			});
			if (open) {
				openModelElement(newMEInstance, ecpProject);
			}
			return newMEInstance;
		}
		return null;
	}

	/**
	 * @param newMEType
	 * @return
	 */
	private static EObject createModelElementInstance(final EClass newMEType) {
		final EPackage ePackage = newMEType.getEPackage();
		final EObject newMEInstance = ePackage.getEFactoryInstance().create(newMEType);
		return newMEInstance;
	}

	/**
	 * @param ecpProject
	 * @param shell
	 * @param open
	 * @return
	 */
	private static EClass openSelectModelElementWizard(final ECPProject ecpProject, final Shell shell, boolean open) {
		final SelectionComposite<TreeViewer> helper = ECPCompositeFactory.getSelectModelClassComposite(ecpProject);
		final SelectModelElementWizard wizard = new SelectModelElementWizard(
			Messages.NewModelElementWizardHandler_Title,
			Messages.NewModelElementWizard_WizardTitle_AddModelElement,
			Messages.NewModelElementWizard_PageTitle_AddModelElement,
			Messages.NewModelElementWizard_PageDescription_AddModelElement);
		wizard.setCompositeProvider(helper);
		final WizardDialog wd = new WizardDialog(shell, wizard);

		final int wizardResult = wd.open();
		if (wizardResult == Window.OK) {
			final Object[] selection = helper.getSelection();
			if (selection != null && selection.length > 0) {
				return (EClass) selection[0];
			}
		}
		return null;
	}

	/**
	 * This method allows the user to filter the visible packages and classes.
	 *
	 * @param ecpProject the project to filter
	 * @param shell the {@link Shell} to use for UI
	 */
	public static void filterProjectPackages(final ECPProject ecpProject, final Shell shell) {
		final Set<EPackage> ePackages = ECPUtil.getAllRegisteredEPackages();

		final CheckedModelClassComposite checkedModelComposite = ECPCompositeFactory
			.getCheckedModelClassComposite(ePackages);
		final Set<Object> initialSelectionSet = new HashSet<Object>();
		initialSelectionSet.addAll(((InternalProject) ecpProject).getVisiblePackages());
		initialSelectionSet.addAll(((InternalProject) ecpProject).getVisibleEClasses());
		checkedModelComposite.setInitialSelection(initialSelectionSet.toArray());

		final FilterModelElementWizard wizard = new FilterModelElementWizard();
		wizard.setCompositeProvider(checkedModelComposite);
		final WizardDialog wd = new WizardDialog(shell, wizard);

		final int wizardResult = wd.open();
		if (wizardResult == Window.OK) {
			final Object[] dialogSelection = checkedModelComposite.getChecked();
			final Set<EPackage> filtererdPackages = new HashSet<EPackage>();
			final Set<EClass> filtererdEClasses = new HashSet<EClass>();
			for (final Object object : dialogSelection) {
				if (object instanceof EPackage) {
					filtererdPackages.add((EPackage) object);
				} else if (object instanceof EClass) {
					final EClass eClass = (EClass) object;
					if (!filtererdPackages.contains(eClass.getEPackage())) {
						filtererdEClasses.add(eClass);
					}
				}
			}
			((InternalProject) ecpProject).setVisiblePackages(filtererdPackages);
			((InternalProject) ecpProject).setVisibleEClasses(filtererdEClasses);
		}
	}

	/**
	 * This method created a new Repository.
	 *
	 * @param shell the shell for the Wizard
	 * @return the created {@link ECPRepository}
	 */
	public static ECPRepository createRepository(final Shell shell) {
		final AddRepositoryComposite addRepositoryComposite = ECPCompositeFactory.getAddRepositoryComposite();
		final AddRepositoryWizard wizard = new AddRepositoryWizard();
		wizard.setCompositeProvider(addRepositoryComposite);
		final WizardDialog wd = new WizardDialog(shell, wizard);

		final int wizardResult = wd.open();
		if (wizardResult == Window.OK) {
			final ECPRepository ecpRepository = ECPUtil.getECPRepositoryManager().addRepository(
				addRepositoryComposite.getProvider(), addRepositoryComposite.getRepositoryName(),
				addRepositoryComposite.getRepositoryLabel() == null ? "" : addRepositoryComposite.getRepositoryLabel(), //$NON-NLS-1$
				addRepositoryComposite.getRepositoryDescription() == null ? "" //$NON-NLS-1$
					: addRepositoryComposite
						.getRepositoryDescription(),
				addRepositoryComposite.getProperties());
			return ecpRepository;
		}
		return null;
	}

	/**
	 * This method closes/opens an array of ECPProject.
	 *
	 * @param closeables the {@link ECPProject}s to change the state for
	 * @param currentType the action to do
	 */
	public static void changeCloseState(ECPProject[] closeables, String currentType) {
		for (final ECPProject closeable : closeables) {
			if ("open".equalsIgnoreCase(currentType)) { //$NON-NLS-1$
				closeable.open();
			} else if ("close".equalsIgnoreCase(currentType)) { //$NON-NLS-1$
				closeable.close();
			}
		}
	}

	/**
	 * Deletes the provided {@link ECPContainer} elements.
	 *
	 * @param deletables the List of {@link ECPContainer}s to delete
	 * @param shell the shell to use for UI
	 */
	public static void deleteHandlerHelper(List<ECPContainer> deletables, Shell shell) {

		if (!deletables.isEmpty()) {
			final DeleteDialog dialog = new DeleteDialog(shell, deletables);
			if (dialog.open() == Window.OK) {
				for (final ECPContainer deletable : deletables) {
					deletable.delete();
				}
			}
		}
	}

	/**
	 * Triggers the save on an {@link ECPProject}.
	 *
	 * @param project the project to save the changes on
	 */
	public static void saveProject(ECPProject project) {
		project.saveContents();
	}

	/**
	 * Resolve the a {@link ECPModelElementOpener} for the given model element.
	 *
	 * @param modelElement the element to find a opener for
	 * @return a {@link ECPModelElementOpener} or null if no opener has been found
	 *
	 * @since 1.12
	 */
	public static ECPModelElementOpener resolveElementOpener(final Object modelElement) {
		if (modelElement == null) {
			MessageDialog.openError(Display.getCurrent().getActiveShell(),
				Messages.ActionHelper_ErrorTitle_ElementDeleted, Messages.ActionHelper_ErrorMessage_ElementDeleted);
			return null;
		}
		IConfigurationElement[] modelelementopener = Platform.getExtensionRegistry().getConfigurationElementsFor(
			"org.eclipse.emf.ecp.ui.modelElementOpener"); //$NON-NLS-1$
		ECPModelElementOpener bestCandidate = null;
		int bestValue = -1;
		for (final IConfigurationElement element : modelelementopener) {
			modelelementopener = null;
			try {
				final ECPModelElementOpener modelelementOpener = (ECPModelElementOpener) element
					.createExecutableExtension("class"); //$NON-NLS-1$
				for (final IConfigurationElement testerElement : element.getChildren()) {
					if ("staticTester".equals(testerElement.getName())) {//$NON-NLS-1$
						final int priority = Integer.parseInt(testerElement.getAttribute("priority"));//$NON-NLS-1$
						final String type = testerElement.getAttribute("modelElement"); //$NON-NLS-1$
						try {
							final Class<?> supportedClassType = HandlerHelperUtil.loadClass(testerElement
								.getContributor().getName(),
								type);
							if (supportedClassType.isInstance(modelElement)) {
								if (priority > bestValue) {
									bestCandidate = modelelementOpener;
									bestValue = priority;
								}
							}

						} catch (final ClassNotFoundException ex) {
							Activator.log(ex);
						}
					} else if ("dynamicTester".equals(testerElement.getName())) {//$NON-NLS-1$
						final ECPModelElementOpenTester tester = (ECPModelElementOpenTester) testerElement
							.createExecutableExtension("tester"); //$NON-NLS-1$
						final int value = tester.isApplicable(modelElement);
						if (value > bestValue) {
							bestCandidate = modelelementOpener;
							bestValue = value;
						}
					}
				}

			} catch (final CoreException e) {

				Activator.log(e);
			}
		}
		return bestCandidate;
	}

	/**
	 * Open a view for the given model element.
	 *
	 * @param modelElement
	 *            ModelElement to open
	 *            the view that requested the open model element
	 * @param ecpProject the {@link ECPProject} of the model element
	 */
	public static void openModelElement(final Object modelElement, ECPProject ecpProject) {
		openModelElement(modelElement, ecpProject, new LinkedHashMap<Object, Object>());
	}

	/**
	 * Open a view for the given model element.
	 *
	 * @param modelElement
	 *            ModelElement to open
	 *            the view that requested the open model element
	 * @param ecpProject the {@link ECPProject} of the model element
	 * @param contextMap context map
	 * @since 1.12
	 */
	public static void openModelElement(final Object modelElement, ECPProject ecpProject,
		Map<Object, Object> contextMap) {

		final ECPModelElementOpener opener = resolveElementOpener(modelElement);

		// TODO: find solution
		// ECPWorkspaceManager.getObserverBus().notify(ModelElementOpenObserver.class).onOpen(me, sourceView, name);
		// BEGIN SUPRESS CATCH EXCEPTION
		if (opener == null) {
			return;
		}
		try {
			if (opener instanceof ECPModelElementOpenerWithContext) {
				((ECPModelElementOpenerWithContext) opener).openModelElement(modelElement, ecpProject, contextMap);
			} else {
				opener.openModelElement(modelElement, ecpProject);
			}
		} catch (final RuntimeException e) {
			Activator.log(e);
		}
		// END SUPRESS CATCH EXCEPTION

	}

	/**
	 * Opens a Dialog showing the properties of the provided {@link ECPProject}.
	 *
	 * @param project the project whose properties should be shown
	 * @param editable whether the properties should be editable
	 * @param shell the {@link Shell} to use for the dialog
	 */
	public static void openProjectProperties(ECPProject project, boolean editable, Shell shell) {
		new ProjectPropertiesDialog(shell, editable, project).open();
	}

	/**
	 * Opens a Dialog showing the properties of the provided {@link ECPRepository}.
	 *
	 * @param repository the repository whose properties should be shown
	 * @param editable whether the properties should be editable
	 * @param shell the {@link Shell} to use for the dialog
	 */
	public static void openRepositoryProperties(ECPRepository repository, boolean editable, Shell shell) {
		new RepositoryPropertiesDialog(shell, editable, repository).open();
	}

	/**
	 * Opens a dialog to save dirty projects.
	 *
	 * @param shell to open the dialog in
	 * @return if the save was triggered
	 */
	public static boolean showDirtyProjectsDialog(Shell shell) {
		final ECPProjectManager manager = ECPUtil.getECPProjectManager();

		final List<ECPProject> dirtyProjects = new ArrayList<ECPProject>();
		for (final ECPProject project : manager.getProjects()) {
			if (project.isOpen() && project.hasDirtyContents()) {
				dirtyProjects.add(project);
			}
		}
		if (dirtyProjects.isEmpty()) {
			return true;
		}
		final ListSelectionDialog lsd = new ListSelectionDialog(shell, dirtyProjects,
			ArrayContentProvider.getInstance(),
			new LabelProvider() {

				@Override
				public Image getImage(Object element) {
					if (ECPProject.class.isInstance(element)) {
						return Activator.getImage("icons/project_open.gif"); //$NON-NLS-1$
					}
					return super.getImage(element);
				}

				@Override
				public String getText(Object element) {
					if (ECPProject.class.isInstance(element)) {
						return ((ECPProject) element).getName();
					}
					return super.getText(element);
				}

			}, "Select the projects, which should be saved."); //$NON-NLS-1$
		lsd.setInitialSelections(manager.getProjects().toArray());
		lsd.setTitle("Unsaved Projects"); //$NON-NLS-1$
		final int result = lsd.open();
		if (Window.OK == result) {
			for (final Object o : lsd.getResult()) {
				ECPHandlerHelper.saveProject((ECPProject) o);
			}
			return true;
		}
		return false;
	}

}
