/*****************************************************************************
 * Copyright (c) 2019 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:
 *  Xavier Le Pallec (for CEA LIST) xlepallec@lilo.org - Bug 558456
 *
 *****************************************************************************/

package org.eclipse.papyrus.uml.diagram.clazz.lf.classtextualedition.mapping.js2java;

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

import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.papyrus.infra.core.services.ServiceException;
import org.eclipse.papyrus.infra.emf.utils.ServiceUtilsForEObject;
import org.eclipse.papyrus.infra.gmfdiag.common.editpart.ResizeableListCompartmentEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.ClassAttributeCompartmentEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.ClassAttributeCompartmentEditPartCN;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.ClassOperationCompartmentEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.ClassOperationCompartmentEditPartCN;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.OperationForClassEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.PropertyForClassEditPart;
import org.eclipse.papyrus.uml.diagram.clazz.lf.classtextualedition.Activator;
import org.eclipse.papyrus.uml.diagram.clazz.lf.classtextualedition.mapping.jsonstructures.JsonUmlClass;
import org.eclipse.papyrus.uml.diagram.clazz.lf.classtextualedition.mapping.jsonstructures.JsonUmlOperation;
import org.eclipse.papyrus.uml.diagram.clazz.lf.classtextualedition.mapping.jsonstructures.JsonUmlProperty;
import org.eclipse.papyrus.uml.diagram.clazz.lf.classtextualedition.messages.Messages;
//import org.eclipse.papyrus.uml.diagram.clazz.edit.parts.ClassEditPart;
import org.eclipse.papyrus.uml.diagram.common.editparts.ClassEditPart;
import org.eclipse.uml2.uml.Operation;
import org.eclipse.uml2.uml.Property;

/**
 * This class aims at fulfilling the class edit part according to a textual
 * definition of a class (UmlClass) with cascading actions for properties and
 * operations.<BR>
 * It has to add new properties/operations and removing previous existing ones
 * that do not appear in the textual definition anymore. That's the reason there
 * are a lot of java attributes: to memorize previous existing elements.
 *
 */
public class JsonUmlClassToEditPart {

	private static final Activator LOGGER = Activator.getDefault();

	private JsonUmlClass theClass;
	private ClassEditPart editPart;
	private org.eclipse.uml2.uml.Class papyrusUmlClass;
	private TransactionalEditingDomain editingDomain;
	private ResizeableListCompartmentEditPart attributeCompartment;
	private ResizeableListCompartmentEditPart operationCompartment;
	private Map<String, org.eclipse.uml2.uml.Property> properties;
	private Map<String, PropertyForClassEditPart> propertyEditParts;
	private Map<String, OperationForClassEditPart> operationEditParts;
	private Map<String, org.eclipse.uml2.uml.Operation> operations;

	/**
	 * This constructor takes a textual definition (UmlClass) and a Papyrus Class
	 * (referenced by the class edit part).<BR>
	 * The constructor creates all the structures to remember the state of the class
	 * before the edition.<BR>
	 * Finally the constructor launches all the process: fetch previous existing
	 * element and the mapping (replacing/adding/removing).
	 *
	 * @param theClass
	 *            textual definition.
	 * @param editPart
	 *            a Papyrus Class (GEF-level)
	 */
	public JsonUmlClassToEditPart(JsonUmlClass theClass, ClassEditPart editPart) {
		super();
		try {
			this.editPart = editPart;
			this.theClass = theClass;
			this.properties = new HashMap<>();
			this.propertyEditParts = new HashMap<>();
			this.operations = new HashMap<>();
			this.operationEditParts = new HashMap<>();

			fetchPapyrusUmlElements();
			updatePapyrusUmlClassAccordingTextualVersion();
		} catch (Exception ex) {
			LOGGER.logError(ex.toString(), ex);
		}
	}

	/**
	 * Load all the elements of the Papyrus class (the update is not done yet). This
	 * method calls the other fetch methods.
	 */
	private void fetchPapyrusUmlElements() {

		if (this.editPart.getModel() instanceof View) {

			View model = View.class.cast(this.editPart.getModel());

			if (model.getElement() instanceof org.eclipse.uml2.uml.Class) {

				this.papyrusUmlClass = org.eclipse.uml2.uml.Class.class.cast(model.getElement());

				List<?> children = editPart.getChildren();
				for (Object child : children) {
					if (child instanceof ClassAttributeCompartmentEditPart || child instanceof ClassAttributeCompartmentEditPartCN) {
						this.attributeCompartment = ResizeableListCompartmentEditPart.class.cast(child);
						fetchAllAttributes();
					} else if (child instanceof ClassOperationCompartmentEditPart || child instanceof ClassOperationCompartmentEditPartCN) {
						this.operationCompartment = ResizeableListCompartmentEditPart.class.cast(child);
						fetchAllOperations();
					}
				}

				try {
					this.editingDomain = ServiceUtilsForEObject.getInstance()
							.getTransactionalEditingDomain(papyrusUmlClass);
				} catch (ServiceException ex) {
					LOGGER.logError(ex.toString(), ex);
				}
			} else {
				LOGGER.logCastProblem("model.getElement()", org.eclipse.uml2.uml.Class.class); //$NON-NLS-1$
			}
		} else {
			LOGGER.logCastProblem("editPart.getModel()", View.class); //$NON-NLS-1$
		}

	}

	/**
	 * This methods create a global command encapsulating the commands for updating
	 * the name, the properties and the operations. It calls the process* methods.
	 */
	private void updatePapyrusUmlClassAccordingTextualVersion() {

		Command globalCommand = createGlobalCommand();
		if (!theClass.getName().equals(papyrusUmlClass.getName())) {
			globalCommand = globalCommand.chain(commandForSettingName());
		}
		globalCommand = processProperties(globalCommand);
		globalCommand = processOperations(globalCommand);

		editingDomain.getCommandStack().execute(globalCommand);

	}

	/**
	 * This method creates an empty command that will be used to give a name to the
	 * global command.
	 *
	 * @return the empty/naming command.
	 */
	private RecordingCommand createGlobalCommand() {

		return new RecordingCommand(editingDomain, Messages.JsonUmlClassToEditPart_TextualEditionOf_TitleCommand + this.papyrusUmlClass.getName()) {
			@Override
			protected void doExecute() {
				// no actions to perform
				// it's just a command to give a name to the global command.
			}
		};
	}

	/**
	 * This method creates a command to updating/setting the name of the class.
	 *
	 * @return the naming command.
	 */
	private Command commandForSettingName() {
		return new RecordingCommand(editingDomain, Messages.JsonUmlClassToEditPart_SetNameCommand_TitleCommand) {
			@Override
			protected void doExecute() {
				papyrusUmlClass.setName(theClass.getName());
			}
		};
	}

	/**
	 * This method call {@link JsonUmlClassToEditPart#fetchAttribute(Object)} for each
	 * attribute in the properties compartment.
	 */
	private void fetchAllAttributes() {
		for (Object child : attributeCompartment.getChildren()) {
			if (child instanceof PropertyForClassEditPart) {
				fetchAttribute(PropertyForClassEditPart.class.cast(child));
			}
		}
	}

	/**
	 * This method call {@link JsonUmlClassToEditPart#fetchOperation(Object)} for each
	 * operation in the operations compartment.
	 */
	private void fetchAllOperations() {
		for (Object child : operationCompartment.getChildren()) {
			if (child instanceof OperationForClassEditPart) {
				fetchOperation(OperationForClassEditPart.class.cast(child));
			}
		}
	}

	/**
	 * This method gets real property and its associated element (edit part and the
	 * notation element) and stores them in the corresponding maps.
	 *
	 * @param child
	 *            the property edit part
	 */
	private void fetchAttribute(PropertyForClassEditPart propertyEditPart) {
		if (propertyEditPart.getModel() instanceof View) {
			View visualStuff = View.class.cast(propertyEditPart.getModel());
			if (visualStuff.getElement() instanceof Property) {
				Property property = Property.class.cast(visualStuff.getElement());

				this.propertyEditParts.put(property.getName(), propertyEditPart);
				this.properties.put(property.getName(), property);
			} else {
				LOGGER.logCastProblem("visualStuff.getElement()", Property.class); //$NON-NLS-1$
			}
		} else {
			LOGGER.logCastProblem("propertyEditPart.getModel()", View.class); //$NON-NLS-1$
		}
	}

	/**
	 * This method gets real operation and its associated element (edit part and the
	 * notation element) and stores them in the corresponding maps.
	 *
	 * @param child
	 *            the operation edit part
	 */
	private void fetchOperation(OperationForClassEditPart operationEditPart) {
		if (operationEditPart.getModel() instanceof View) {
			View visualStuff = View.class.cast(operationEditPart.getModel());
			if (visualStuff.getElement() instanceof Operation) {
				Operation operation = (Operation) visualStuff.getElement();

				this.operationEditParts.put(operation.getName(), operationEditPart);
				this.operations.put(operation.getName(), operation);
			} else {
				LOGGER.logCastProblem("visualStuff.getElement()", Operation.class); //$NON-NLS-1$
			}
		} else {
			LOGGER.logCastProblem("operationEditPart.getModel()", View.class); //$NON-NLS-1$
		}
	}

	/**
	 * Get the list of the real properties found in the class edit part.
	 *
	 * @return list of the real properties
	 */
	private Property[] getAllAttributes() {
		return this.properties.values().toArray(new Property[0]);
	}

	/**
	 * Get the list of the real operations found in the class edit part.
	 *
	 * @return list of the real operations
	 */
	private Operation[] getAllOperations() {
		return this.operations.values().toArray(new Operation[0]);
	}

	/**
	 * This method updates the properties.<BR>
	 * First, for each property in the textual definition of the class, it looks if
	 * a property in the papyrus class exists with the same name. If it is, it
	 * updates it and removes it from the list of properties to actually remove. If
	 * not, it creates a new property.<BR>
	 * Second, all the existing properties that have not been "met" are removed.
	 *
	 * @param globalCommand
	 *            the global command on which all the properties edition
	 *            commands will be chained with.
	 * @return the new global command.
	 */
	private Command processProperties(Command globalCommand) {
		try {

			for (JsonUmlProperty property : theClass.getProperties()) {
				Property papyrusProperty = properties.get(property.getName());
				if (papyrusProperty != null) {
					globalCommand = globalCommand
							.chain(ToEditPartFactory.getInstance().createJsonUmlPropertyToEditPart(editingDomain, editPart, attributeCompartment)
									.commandForUpdatingProperty(property, papyrusProperty));

					properties.remove(property.getName(), papyrusProperty);
				} else {
					globalCommand = globalCommand
							.chain(ToEditPartFactory.getInstance().createJsonUmlPropertyToEditPart(editingDomain, editPart, attributeCompartment)
									.commandForAddingProperty(property));
				}
			}
			for (Property papyrusProperty : getAllAttributes()) {
				globalCommand = globalCommand
						.chain(ToEditPartFactory.getInstance().createJsonUmlPropertyToEditPart(editingDomain, editPart, attributeCompartment)
								.commandForRemovingProperty(propertyEditParts, papyrusProperty));
			}
		} catch (Exception ex) {
			LOGGER.logError(ex.toString(), ex);
		}
		return globalCommand;
	}

	/**
	 * This method updates the operations.<BR>
	 * First, for each operation in the textual definition of the class, it looks if
	 * an operation in the papyrus class exists with the same name. If it is, it
	 * updates it and removes it from the list of properties to actually remove. If
	 * not, it creates a new operation.<BR>
	 * Second, all the existing operations that have not been "met" are removed.
	 *
	 * @param globalCommand
	 *            the global command on which all the operations edition
	 *            commands will be chained with.
	 * @return the new global command.
	 */
	private Command processOperations(Command globalCommand) {
		try {
			for (JsonUmlOperation operation : theClass.getOperations()) {
				Operation papyrusOperation = operations.get(operation.getName());
				if (papyrusOperation != null) {
					globalCommand = globalCommand
							.chain(ToEditPartFactory.getInstance().createJsonUmlOperationToEditPart(editingDomain, editPart, operationCompartment)
									.commandForUpdatingOperation(operation, papyrusOperation));
					operations.remove(operation.getName(), papyrusOperation);
				} else {
					globalCommand = globalCommand
							.chain(ToEditPartFactory.getInstance().createJsonUmlOperationToEditPart(editingDomain, editPart, operationCompartment)
									.commandForAddingOperation(operation));
				}
			}
			for (Operation papyrusOperation : getAllOperations()) {
				globalCommand = globalCommand
						.chain(ToEditPartFactory.getInstance().createJsonUmlOperationToEditPart(editingDomain, editPart, operationCompartment)
								.commandForRemovingOperation(operationEditParts, papyrusOperation));
			}
		} catch (Exception ex) {
			LOGGER.logError(ex.toString(), ex);
		}
		return globalCommand;
	}

}
