/*******************************************************************************
 * Copyright (c) 2014, 2018 CEA LIST 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:
 *   E.D.Willink (CEA LIST) - initial API and implementation
 *******************************************************************************/
package org.eclipse.ocl.xtext.base.ui.commands;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.commands.HandlerEvent;
import org.eclipse.core.commands.IHandlerListener;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.ui.dialogs.DiagnosticDialog;
import org.eclipse.emf.common.ui.viewer.IViewerProvider;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
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.util.Diagnostician;
import org.eclipse.emf.ecore.util.EObjectValidator;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.edit.domain.AdapterFactoryEditingDomain;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.domain.IEditingDomainProvider;
import org.eclipse.emf.edit.ui.EMFEditUIPlugin;
import org.eclipse.emf.edit.ui.action.ValidateAction;
import org.eclipse.emf.edit.ui.provider.DiagnosticDecorator;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.window.Window;
import org.eclipse.ocl.pivot.internal.utilities.PivotDiagnostician;
import org.eclipse.ocl.pivot.utilities.ClassUtil;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ISetSelectionTarget;

public class ValidateCommand extends ValidateAction
{
	@Override
	protected Diagnostician createDiagnostician(AdapterFactory adapterFactory, @Nullable IProgressMonitor progressMonitor) {
		ResourceSet resourceSet = ClassUtil.nonNullEMF(domain.getResourceSet());
		return PivotDiagnostician.createDiagnostician(resourceSet, adapterFactory, progressMonitor);
	}

	/**
	 * Fires an event to all registered listeners describing changes to this
	 * instance.
	 * <p>
	 * Subclasses may extend the definition of this method (i.e., if a different
	 * type of listener can be attached to a subclass). This is used primarily
	 * for support of <code>AbstractHandler</code> in
	 * <code>org.eclipse.ui.workbench</code>, and clients should be wary of
	 * overriding this behaviour. If this method is overridden, then the first
	 * line of the method should be "<code>super.fireHandlerChanged(handlerEvent);</code>".
	 * </p>
	 * 
	 * @param handlerEvent
	 *            the event describing changes to this instance. Must not be
	 *            <code>null</code>.
	 */
	protected void fireHandlerChanged(final HandlerEvent handlerEvent) {
		if (handlerEvent == null) {
			throw new NullPointerException();
		}
		final Object[] listeners = getListeners();
		for (int i = 0; i < listeners.length; i++) {
			final IHandlerListener listener = (IHandlerListener) listeners[i];
			listener.handlerChanged(handlerEvent);
		}
	}

	@Override	// FIXME BUG 435735 Overridden to select resource more intelligently for Papyrus
	protected void handleDiagnostic(Diagnostic diagnostic) {
		IWorkbenchWindow activeWorkbenchWindow = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
		if (activeWorkbenchWindow == null) {
			return;
		}
		int severity = diagnostic.getSeverity();
		String title = null;
		String message = null;

		if (severity == Diagnostic.ERROR || severity == Diagnostic.WARNING) {
			title = EMFEditUIPlugin.INSTANCE.getString("_UI_ValidationProblems_title");
			message = EMFEditUIPlugin.INSTANCE.getString("_UI_ValidationProblems_message");
		} else {
			title = EMFEditUIPlugin.INSTANCE
				.getString("_UI_ValidationResults_title");
			message = EMFEditUIPlugin.INSTANCE .getString(severity == Diagnostic.OK
					? "_UI_ValidationOK_message"
					: "_UI_ValidationResults_message");
		}

		int result = 0;
		if (diagnostic.getSeverity() == Diagnostic.OK) {
			MessageDialog.openInformation(activeWorkbenchWindow.getShell(), title, message);
			result = Window.CANCEL;
		} else {
			result = DiagnosticDialog.open(activeWorkbenchWindow.getShell(), title, message, diagnostic);
		}

		ResourceSet resourceSet = domain.getResourceSet();
		// The following lines replace the simple inherited assumption of resourceSet.getResources().get(0)
		Resource resource = null;
		if (eclipseResourcesUtil != null) {
			List<?> data = diagnostic.getData();
			if ((data != null) && (data.size() >= 1)) {
				Object object = data.get(0);
				if (object instanceof EObject) {
					resource = ((EObject)object).eResource();
				}
			}
			if (resource == null) {
				resource = resourceSet.getResources().get(0);
			}
		}
		if (resource != null) {
			eclipseResourcesUtil.deleteMarkers(resource);
		}

		if (result == Window.OK) {
			if (!diagnostic.getChildren().isEmpty()) {
				List<?> data = (diagnostic.getChildren().get(0)).getData();
				if (!data.isEmpty() && data.get(0) instanceof EObject) {
					Object part = activeWorkbenchWindow.getActivePage().getActivePart();
					if (part instanceof ISetSelectionTarget) {
						((ISetSelectionTarget) part).selectReveal(new StructuredSelection(data.get(0)));
					} else if (part instanceof IViewerProvider) {
						Viewer viewer = ((IViewerProvider) part).getViewer();
						if (viewer != null) {
							viewer.setSelection(new StructuredSelection(data.get(0)), true);
						}
					}
				}
			}

			if (resource != null) {
				for (Diagnostic childDiagnostic : diagnostic.getChildren()) {
					eclipseResourcesUtil.createMarkers(resource, childDiagnostic);
				}
			}
		} else {
			// Trigger direct updating of decorations, if there are adapters.
			//
			resource = null;
		}

		if (resource == null) {
			// If no markers are produced the decorator won't be able to respond
			// to marker resource deltas, so inform it directly.
			//

			// Create a diagnostic for the resource set as a whole.
			//
			BasicDiagnostic resourceSetDiagnostic = new BasicDiagnostic(EObjectValidator.DIAGNOSTIC_SOURCE, 0, null, new Object[]{resourceSet});

			// Create a diagnostic for each resource.
			//
			Map<Resource, BasicDiagnostic> resourceDiagnostics = new LinkedHashMap<Resource, BasicDiagnostic>();
			for (Resource r : resourceSet.getResources()) {
				BasicDiagnostic resourceDiagnostic = new BasicDiagnostic(EObjectValidator.DIAGNOSTIC_SOURCE, 0, null, new Object[]{r});
				resourceDiagnostics.put(r, resourceDiagnostic);
			}

			// Just clean up decorations if the dialog was cancelled.
			//
			if (result == Dialog.OK) {
				// Partition the children among the resource diagnostics.
				//
				for (Diagnostic child : diagnostic.getChildren()) {
					List<?> data = child.getData();
					if (!data.isEmpty()) {
						Object object = data.get(0);
						if (object instanceof EObject) {
							BasicDiagnostic resourceDiagnostic = resourceDiagnostics.get(((EObject) object).eResource());
							if (resourceDiagnostic != null) {
								resourceDiagnostic.add(child);
							}
						}
					}
				}
			}

			// Add the resource diagnostics to the resource set diagnostic.
			//
			for (Diagnostic resourceDiagnostic : resourceDiagnostics.values()) {
				resourceSetDiagnostic.add(resourceDiagnostic);
			}

			// Inform any decorators.
			//
			try {
				DiagnosticDecorator.DiagnosticAdapter.update(resourceSet, resourceSetDiagnostic);
			}
			catch (Throwable e) {}		// Expect class load failure on EMF 2.8
		}
	}

	/**
	 * <p>
	 * Returns true iff there is one or more IHandlerListeners attached to this
	 * AbstractHandler.
	 * </p>
	 * <p>
	 * Subclasses may extend the definition of this method (i.e., if a different
	 * type of listener can be attached to a subclass). This is used primarily
	 * for support of <code>AbstractHandler</code> in
	 * <code>org.eclipse.ui.workbench</code>, and clients should be wary of
	 * overriding this behaviour. If this method is overridden, then the return
	 * value should include "<code>super.hasListeners() ||</code>".
	 * </p>
	 * 
	 * @return true iff there is one or more IHandlerListeners attached to this
	 *         AbstractHandler
	 */
	protected boolean hasListeners() {
		return isListenerAttached();
	}

	@Override
	public void setActiveWorkbenchPart(IWorkbenchPart workbenchPart) {
		Object object = workbenchPart.getAdapter(EditingDomain.class);
		if (object instanceof EditingDomain) {
			domain = (EditingDomain)object;
			return;
		}
		object = workbenchPart.getAdapter(IEditingDomainProvider.class);
		if (object instanceof IEditingDomainProvider) {
			domain = ((IEditingDomainProvider)object).getEditingDomain();
			return;
		}
		if (workbenchPart instanceof IEditingDomainProvider) {
			domain = ((IEditingDomainProvider) workbenchPart).getEditingDomain();
		}
	}

	@Override
	public boolean updateSelection(IStructuredSelection selection) {
		selectedObjects = new ArrayList<EObject>();
		for (Iterator<?> objects = selection.iterator(); objects.hasNext();) {
			Object object = AdapterFactoryEditingDomain.unwrap(objects.next());
			if (object instanceof IAdaptable) {
				object = ((IAdaptable) object).getAdapter(EObject.class);
			}
			if (object instanceof EObject) {
				selectedObjects.add((EObject) object);
			} else if (object instanceof Resource) {
				selectedObjects.addAll(((Resource) object).getContents());
			} else {
				return false;
			}
		}
		selectedObjects = EcoreUtil.filterDescendants(selectedObjects);
		return !selectedObjects.isEmpty();
	}
}
