/*******************************************************************************
 * Copyright (c) 2009, 2018 SAP AG 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:
 *     SAP AG - initial API and implementation
 ******************************************************************************/
package org.eclipse.ocl.examples.impactanalyzer.editor;

import java.lang.reflect.InvocationTargetException;
import java.util.Collection;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.ui.MarkerHelper;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EValidator;
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.EcoreUtil;
import org.eclipse.emf.edit.ui.EMFEditUIPlugin;
import org.eclipse.emf.edit.ui.action.ValidateAction;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.ocl.ecore.OCL;
import org.eclipse.ocl.ecore.OCLExpression;
import org.eclipse.ocl.ecore.opposites.OppositeEndFinder;
import org.eclipse.ocl.examples.impactanalyzer.ImpactAnalyzer;
import org.eclipse.ocl.examples.impactanalyzer.util.OCLFactory;
import org.eclipse.ui.PlatformUI;


/**
 * Validates a specific constraint on one or more of the context elements that are instance of the constaint's context class or a
 * subclass thereof.
 * <p>
 * 
 * There are {@link Diagnostic} objects maintained as {@link Resource#getErrors() errors} and {@link Resource#getWarnings()
 * warnings} of an EMF resource, and {@link IMarker} objects managed by {@link IResource}s and stored persistently in the
 * workspace, representing validation errors. {@link MarkerHelper} and its subclasses can turn {@link Diagnostic} objects into
 * {@link IMarker}s which form the basis for the problem view display. A {@link MarkerHelper} is used to create {@link IMarker
 * markers} from {@link Diagnostic} objects. Specializations of {@link MarkerHelper} can annotate the markers with additional
 * information stored, e.g., in {@link Diagnostic#getData()} and storing them in {@link IMarker#getAttribute(String) attributes}
 * of the marker. By default, this process is triggered in the <code>updateProblemIndication</code> method of a generated EMF
 * sample editor, where first all markers for the entire {@link ResourceSet} (this seems too broad a scope) are deleted and then
 * created again based on the {@link Diagnostic}s returned from {@link Resource#getErrors()} and {@link Resource#getWarnings()}
 * for the resources contained by the editing domain's resource set.
 * <p>
 * 
 * EMF resources, upon loading, don't perform any constraint validation. Therefore, their errors and warnings list turns out empty
 * by default. Filling those has to happen by explicitly performing a {@link ValidateAction} on selected resources or individual
 * elements. Only then will a {@link Diagnostician} be used to fetch the {@link EValidator} from the validator registry with which
 * a validation is performed on a single {@link EObject}. Such a validation run will produce {@link Diagnostic} objects which the
 * {@link ValidateAction} then converts into {@link IMarker}s again. Note that these {@link Diagnostic} objects are <em>not</em>
 * entered into the errors/warnings of the {@link Resource} on which the validation happened.
 * <p>
 * 
 * When a change {@link Notification} triggers this revalidation action, the constraint is re-evaluated on the context objects
 * determined by the {@link ImpactAnalyzer OCL Impact Analysis}. For any constraint which now evaluates to <code>true</code>, any
 * existing {@link Diagnostic} needs to be removed. FOr any constraint evaluating to <code>false</code> a {@link Diagnostic}
 * object needs to be created, and an {@link IMarker} needs to be created and displayed in the problem view.
 * <p>
 * 
 * During re-validation, the resources of other objects on which to evaluate the constraint may be loaded into the surrounding
 * editing domain's resource set. Markers are managed by a <code>MarkerManager</code> which persistently stores markers in the
 * workspace, keyed by the resources to which they belong.
 * 
 * @author Axel Uhl (D043530)
 * 
 */
public class RevalidateAction extends ValidateAction {
    private static final String MARKER_TYPE = "org.eclipse.core.resources.problemmarker";
    private static final String ELEMENT_URI = "elementuri";
    private static final String CONSTRAINT_NAME = "constraintname";
    private final Collection<EObject> contextObjects;
    private final String constraintName;
    private final OCLExpression invariant;
    private final OppositeEndFinder oppositeEndFinder;
    private final OCLFactory oclFactory;

    public RevalidateAction(String constraintName, Collection<EObject> contextObjects, OCLExpression invariant, OCLFactory oclFactory, OppositeEndFinder oppositeEndFinder) {
        super();
        this.contextObjects = contextObjects;
        this.constraintName = constraintName;
        this.invariant = invariant;
        this.oclFactory = oclFactory;
        this.oppositeEndFinder = oppositeEndFinder;
    }

    @Override
    public void run() {
        IRunnableWithProgress runnableWithProgress = new IRunnableWithProgress() {
            public void run(final IProgressMonitor progressMonitor) throws InvocationTargetException, InterruptedException {
                try {
                    validateConstraints(progressMonitor);
                } catch (CoreException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        };
        if (eclipseResourcesUtil != null) {
            runnableWithProgress = eclipseResourcesUtil.getWorkspaceModifyOperation(runnableWithProgress);
        }

        try {
            // This runs the operation, and shows progress.
            // (It appears to be a bad thing to fork this onto another thread.)
            //
            PlatformUI.getWorkbench().getProgressService().run(/* fork */ true, /* cancelable */ true, runnableWithProgress);
        } catch (Exception exception) {
            EMFEditUIPlugin.INSTANCE.log(exception);
        }
    }

    /**
     * This simply execute the command.
     */
    private void validateConstraints(IProgressMonitor progressMonitor) throws CoreException {
        int selectionSize = contextObjects.size();
        progressMonitor.beginTask("", selectionSize);
        OCL ocl = oclFactory.createOCL(oppositeEndFinder);
        for (EObject eObject : contextObjects) {
            System.out.println("Re-validating "+constraintName+" on "+EcoreUtil.getURI(eObject));
            IFile fileForContext = getFile(eObject);
            URI eObjectURI = EcoreUtil.getURI(eObject);
            removeMarker(eObjectURI, fileForContext);
            boolean valid = (Boolean) ocl.evaluate(eObject, invariant);
            if (!valid) {
                if (fileForContext != null) {
                    IMarker marker = fileForContext.createMarker(MARKER_TYPE);
                    // TODO here's the place to talk about severities of constraint violations
                    marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
                    marker.setAttribute(IMarker.MESSAGE, "Constraint "+constraintName+" violated on "+eObject);
                    marker.setAttribute(CONSTRAINT_NAME, constraintName);
                    marker.setAttribute(ELEMENT_URI, eObjectURI.toString());
                }
            }
        }
    }

    private void removeMarker(URI eObjectURI, IFile fileForContext) throws CoreException {
        IMarker[] markers = fileForContext.findMarkers(MARKER_TYPE, /* includeSubtypes */ false, IResource.DEPTH_ZERO);
        if (markers != null) {
            for (IMarker marker : markers) {
                if (marker.getAttribute(CONSTRAINT_NAME, "").equals(constraintName) &&
                        marker.getAttribute(ELEMENT_URI, "").equals(eObjectURI.toString())) {
                    marker.delete();
                }
            }
        }
    }

    private IFile getFile(EObject eObject) {
        URI uri = EcoreUtil.getURI(eObject);
        String platformResourceString = uri.toPlatformString(true);
        return platformResourceString != null ? ResourcesPlugin.getWorkspace().getRoot()
                .getFile(new Path(platformResourceString)) : null;
    }

    protected String composeMessage(Diagnostic diagnostic, Diagnostic parentDiagnostic) {
        String message = diagnostic.getMessage();
        if (parentDiagnostic != null) {
            String parentMessage = parentDiagnostic.getMessage();
            if (parentMessage != null) {
                message = message != null ? parentMessage + ". " + message : parentMessage;
            }
        }
        return message;
    }

    protected void createMarkers(IResource resource, Diagnostic diagnostic, Diagnostic parentDiagnostic) throws CoreException {
        if (resource != null && resource.exists()) {
            IMarker marker = resource.createMarker(MARKER_TYPE);
            int severity = diagnostic.getSeverity();
            if (severity < Diagnostic.WARNING) {
                marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_INFO);
            } else if (severity < Diagnostic.ERROR) {
                marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_WARNING);
            } else {
                marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
            }

            String message = composeMessage(diagnostic, parentDiagnostic);
            if (message != null) {
                marker.setAttribute(IMarker.MESSAGE, message);
            }
        }
    }
    
}
