/*****************************************************************************
 * Copyright (c) 2020 CEA LIST
 *
 * 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:
 *    Matteo Morelli - initial API and implementation
 *
 *****************************************************************************/

package org.eclipse.papyrus.robotics.diagrams.advices;

import org.eclipse.core.commands.ExecutionException;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.util.TransactionUtil;
import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
import org.eclipse.gmf.runtime.common.core.command.ICommand;
import org.eclipse.gmf.runtime.emf.type.core.edithelper.AbstractEditHelperAdvice;
import org.eclipse.gmf.runtime.emf.type.core.requests.ConfigureRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyDependentsRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.GetEditContextRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.IEditCommandRequest;
import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.papyrus.designer.transformation.core.transformations.LazyCopier;
import org.eclipse.papyrus.designer.transformation.core.transformations.LazyCopier.CopyExtResources;
import org.eclipse.papyrus.infra.emf.gmf.command.EMFtoGMFCommandWrapper;
import org.eclipse.papyrus.infra.services.edit.service.ElementEditServiceUtils;
import org.eclipse.papyrus.infra.services.edit.service.IElementEditService;
import org.eclipse.papyrus.robotics.core.commands.CancelCommand;
import org.eclipse.papyrus.robotics.core.utils.NamingUtil;
import org.eclipse.papyrus.robotics.diagrams.Activator;
import org.eclipse.papyrus.robotics.profile.robotics.skills.SkillDefinition;
import org.eclipse.papyrus.uml.tools.utils.StereotypeUtil;
import org.eclipse.swt.widgets.Display;
import org.eclipse.uml2.uml.Element;
import org.eclipse.uml2.uml.Interface;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.NamedElement;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.PackageImport;
import org.eclipse.uml2.uml.StateMachine;
import org.eclipse.uml2.uml.Stereotype;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.util.UMLUtil;

/**
 * Edit Helper Advice for creating a new SkillDefinition
 */
public class SkillDefinitionEditHelperAdvice extends AbstractEditHelperAdvice {

	private static final String SKILLDEF_PREFIX 						 = "SkillDefinition"; //$NON-NLS-1$
	private static final String SKILLDEF_DEFAULT_SEMANTICS_NAME_SUFFIX   = "DefaultFSM"; //$NON-NLS-1$
	private static final String SKILLDEF_DEFAULT_SEMANTICS_PKG_NAME 	 = "defaultsemantics";
	private static final String SKILLDEF_DEFAULT_SEMANTICS_TEMPLATE_NAME = "DefaultSkillFSMTemplate";

	boolean errShown = false;

	/**
	 * The attribute which identifies the template definition of default skill semantics
	 */
	StateMachine defSemantics;

	/**
	 * The package in the current model where the template of default skill semantics must be copied
	 */
	Package destPkg;

	/**
	 * The copy of default skill semantics template in the local model
	 */
	StateMachine newDefSemantics;

	/**
	 * Logics to compute the name of the FSM associated to the skill definition
	 */
	protected static String calcFSMName(String skdefName) {
		return skdefName + SKILLDEF_DEFAULT_SEMANTICS_NAME_SUFFIX;
	}

	/**
	 * Utility method to get the default semantics associated to a UML::Operation that represent a skill definition
	 */
	protected static StateMachine getDefaultSemantics(Operation op) {
		StateMachine fsm = null;
		if (op != null) {
			SkillDefinition skdef =  UMLUtil.getStereotypeApplication(op, SkillDefinition.class);
			if (skdef != null && skdef.getDefaultSemantic() != null) {
				fsm = skdef.getDefaultSemantic().getBase_StateMachine();
			}
		}
		return fsm;
	}

	/**
	 *
	 */
	protected static void displayErrorMsgForSkillModelsUnableToManageFSM() {
		Display.getDefault().syncExec(new Runnable() {
			@Override
			public void run() {
				MessageDialog.openWarning(Display.getCurrent().getActiveShell(),
						"Cannot modify the current model",
						String.format("The current model does not support the definition of SkillSemantics.\n"
						+ "See https://wiki.eclipse.org/Papyrus/customizations/robotics/faq#Q:_I_get_the_error_.22Cannot_modify_the_current_model.22_when_I_try_to_modify_an_existing_skill_model"));
			}
		});
	}

    /**
     * Decide whether the requested command should be approved
     */
    @Override
    public ICommand getBeforeEditCommand(IEditCommandRequest request) {
        // The request must fall in the following 3 cases:
        //   - EditContext
        //   - Set
        //   - DestroyDependents
        if (! (request instanceof GetEditContextRequest ||
        		request instanceof SetRequest ||
        		  request instanceof DestroyDependentsRequest)) {
        	return super.getBeforeEditCommand(request);
        }
        // We are in one of the 3 cases above: check model consistency
        Model umlModel = null;
        if (request instanceof GetEditContextRequest) {
        	// EditContext
        	Object elem = ((GetEditContextRequest) request).getEditContext();
        	// (get model)
        	if (elem instanceof Interface)
        		umlModel = ((Interface) elem).getModel();
        }
        else {
        	EObject elem = null;
        	if (request instanceof SetRequest) {
        		// Set
        		elem = ((SetRequest) request).getElementToEdit();
        	}
        	else if (request instanceof DestroyDependentsRequest) {
        		// Destroy
        		elem = ((DestroyDependentsRequest) request).getElementToDestroy();
        	}
        	// (get model)
        	if (elem  instanceof Operation)
    			umlModel = ((Operation) elem).getModel();
        }
        // The request is accepted if the model is consitent with the new version
        if (umlModel != null) {
        	// It must exist a package with name SKILLDEF_DEFAULT_SEMANTICS_PKG_NAME
        	destPkg      = null;
        	for (Element e : umlModel.allOwnedElements())
    			if (e instanceof Package && ((Package) e).getName().equals(SKILLDEF_DEFAULT_SEMANTICS_PKG_NAME))
    				destPkg = (Package) e;
    		// It must exist a template FSM in the imported oepr.library
        	defSemantics = null;
    		for (PackageImport pi : umlModel.getPackageImports()) {
    			NamedElement el = pi.getImportedPackage().getOwnedMember(SKILLDEF_DEFAULT_SEMANTICS_TEMPLATE_NAME);
    			if (el != null) defSemantics = (StateMachine) el;
    		}
    		if (destPkg != null && defSemantics != null) {
    			errShown = false;
    			return super.getBeforeEditCommand(request);
    		}
    		// otherwise -> destPkg == null || defSemantics == null
    		displayErrorMsgForSkillModelsUnableToManageFSM();
    		errShown = true;
        }
        return null;
    }

	/**
	 * Set skill semantics after creation
	 */
	@Override
	protected ICommand getAfterConfigureCommand(ConfigureRequest request) {
		// * Init
		//
		// Get the skill definition which has just been created and the UML model where it is defined
		EObject newElement = request.getElementToConfigure();
		if (!(newElement instanceof Operation)) {
			return super.getAfterConfigureCommand(request);
		}
		// (non-initialized class attributes to null, prepare the command, ...)
		final Operation op = (Operation) newElement;
		final Model umlModel = op.getModel();
		CompositeCommand compositeCommand = new CompositeCommand("SkillDefinition configuration command"); //$NON-NLS-1$

		final IElementEditService commandProvider = ElementEditServiceUtils.getCommandProvider(op);

		SetRequest setSkillDefNameReq = new SetRequest(op, UMLPackage.eINSTANCE.getNamedElement_Name(),
				NamingUtil.getName(op, SKILLDEF_PREFIX, "%04d")); //$NON-NLS-1$
		ICommand setSkillDefNameCmd = commandProvider.getEditCommand(setSkillDefNameReq);
		try {
			setSkillDefNameCmd.execute(null, null);
		} catch (ExecutionException ee) {
			Activator.log.error(ee);
		}

		// * Copy the default semantics template to the 'defaultsemantics' package (provided by the wizard)
		//
		//   - select destination package
		if (destPkg == null) {
			for (Element e : umlModel.allOwnedElements())
				if (e instanceof Package && ((Package) e).getName().equals(SKILLDEF_DEFAULT_SEMANTICS_PKG_NAME))
					destPkg = (Package) e;
		}
		//   - select the FSM to be copied (element in the imported oepr.library)
		if (defSemantics == null) {
			for (PackageImport pi : umlModel.getPackageImports()) {
				NamedElement el = pi.getImportedPackage().getOwnedMember(SKILLDEF_DEFAULT_SEMANTICS_TEMPLATE_NAME);
				if (el != null) defSemantics = (StateMachine) el;
			}
		}
		// The request has already been approved => destPkg and defSemantics cannot be null
		//
		//   - do copy (and change the name according to the one of the skill definition)
		RecordingCommand copyDefSemantics = new RecordingCommand(TransactionUtil.getEditingDomain(defSemantics)) {

			/**
			 * Utility method for copying the stereotype applications of all elements of template FSM
			 * @param copy
			 * @param orig
			 */
			protected void addFSMStereotypesToResources(StateMachine copy, StateMachine orig) {
				// add SkillSemantics stereotype (it's the unique stereotype applied)
				UMLUtil.safeApplyStereotype(copy, orig.getAppliedStereotypes().get(0));
				// visit all the elements
				TreeIterator<EObject> copyIterator = copy.eAllContents();
				TreeIterator<EObject> origIterator = orig.eAllContents();
				while (origIterator.hasNext()) {
					EObject copyObj = copyIterator.next();
					EObject origObj = origIterator.next();
					if (origObj instanceof Element) {
						for (Stereotype s : ((Element) origObj).getAppliedStereotypes()) {
							// apply the stereotype on the copied element
							UMLUtil.safeApplyStereotype((Element) copyObj, s);
						}

					}
				}
			}

			@Override
			protected void doExecute() {
				LazyCopier copier = new LazyCopier(umlModel, destPkg, CopyExtResources.ALL, false);
				newDefSemantics = copier.getCopy(defSemantics);
				newDefSemantics.setName(calcFSMName(op.getName()));             // change name
				//boolean x = StereotypeUtil.isApplied(newDefSemantics, SkillSemantic.class);
				destPkg.getPackagedElements().add(newDefSemantics); 			// stereotype applications are not preserved in the copy
				addFSMStereotypesToResources(newDefSemantics, defSemantics);	// need to navigate the original FSM and do the copy
			}
		};
		copyDefSemantics.execute(); // do not add to compositeCommand but execute it directly

		// * Reference the new FSM as operation method
		RecordingCommand assignDefFSMCmd = new RecordingCommand(TransactionUtil.getEditingDomain(defSemantics)) {
			@Override
			protected void doExecute() {
				op.getMethods().add(newDefSemantics);
			}
		};
		compositeCommand.add(EMFtoGMFCommandWrapper.wrap(assignDefFSMCmd));

		// * Apply the SkillDefinition stereotype to the new element
		RecordingCommand applySkillDefStereotypeCmd = new RecordingCommand(TransactionUtil.getEditingDomain(newElement)) {
			@Override
			protected void doExecute() {
				StereotypeUtil.apply(op, SkillDefinition.class);
			}
		};
		compositeCommand.add(EMFtoGMFCommandWrapper.wrap(applySkillDefStereotypeCmd));

		// Execute the composite command
		return compositeCommand.isEmpty() ? super.getAfterConfigureCommand(request) : compositeCommand;
	}

	/**
	 * Set name of default skill semantics according to that of skill
	 */
	@Override
	protected ICommand getAfterSetCommand(SetRequest request) {
		if (errShown == true) return new CancelCommand(request.getElementToEdit());
		EStructuralFeature feat = request.getFeature();
		EObject newElement      = request.getElementToEdit();
		// Do execute the afterSetCommand only if the modified structural feature is "name"
		// (synch names of skill def and the state machine representing its default semantics)
		if (!(feat.getName().equals("name") && newElement instanceof Operation)) {
			return super.getAfterSetCommand(request);
		}
		final Operation op = (Operation) newElement;
		String newName = (String) request.getValue();
		CompositeCommand compositeCommand = new CompositeCommand("SkillDefinition/SkillSemantic name synch command");
		// * Change name of FSM
		StateMachine fsm = getDefaultSemantics(op);
		if (fsm != null) {
			ICommand setNameCmd = ElementEditServiceUtils.
					getCommandProvider(op).
					getEditCommand(
							new SetRequest(fsm, UMLPackage.eINSTANCE.getNamedElement_Name(), calcFSMName(newName))
							);
			compositeCommand.add(setNameCmd);
		}

		// Eventually execute the composite command
		return compositeCommand.isEmpty() ? super.getAfterSetCommand(request) : compositeCommand;
	}

	@Override
	protected ICommand getBeforeDestroyElementCommand(
			DestroyElementRequest request) {
		if (errShown == true) return new CancelCommand(request.getElementToDestroy());
		return super.getBeforeDestroyElementCommand(request);
	}

	/**
	 * Remove created FSM, if the skill definition is destroyed
	 */
	@Override
	protected ICommand getAfterDestroyDependentsCommand(DestroyDependentsRequest request) {
		if (errShown == true) return new CancelCommand(request.getElementToDestroy());
		// create command and get the skill definition to be destroyed
		CompositeCommand compositeCommand = new CompositeCommand("Skill definition destruction command"); //$NON-NLS-1$
		EObject destroyElement = request.getElementToDestroy();
		if (!(destroyElement instanceof Operation)) {
			return super.getAfterDestroyDependentsCommand(request);
		}
		final Operation op = (Operation) destroyElement;

		// get the associated semantics to be destroyed as well
		StateMachine fsm = getDefaultSemantics(op);
		if (fsm != null) {
			final IElementEditService commandProvider = ElementEditServiceUtils.getCommandProvider(op);
			DestroyElementRequest destroyDepReq = new DestroyElementRequest(fsm, false);
			ICommand destroyDepCmd = commandProvider.getEditCommand(destroyDepReq);
			compositeCommand.add(destroyDepCmd);
		}

		// Eventually execute the composite command
		return compositeCommand.isEmpty() ? super.getAfterDestroyDependentsCommand(request) : compositeCommand;
	}

}