/*******************************************************************************
 * Copyright (c) 2008-2011 Chair for Applied Software Engineering,
 * Technische Universitaet Muenchen.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 * chodnick
 ******************************************************************************/
package org.eclipse.emf.emfstore.internal.client.model.changeTracking;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.emfstore.internal.client.model.util.WorkspaceUtil;
import org.eclipse.emf.emfstore.internal.common.model.ModelElementId;
import org.eclipse.emf.emfstore.internal.common.model.impl.IdEObjectCollectionImpl;
import org.eclipse.emf.emfstore.internal.common.model.impl.ProjectImpl;
import org.eclipse.emf.emfstore.internal.common.model.util.ModelUtil;
import org.eclipse.emf.emfstore.internal.common.model.util.NotificationInfo;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.AbstractOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.AttributeOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.ContainmentType;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.FeatureOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.MultiAttributeMoveOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.MultiAttributeOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.MultiAttributeSetOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.MultiReferenceMoveOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.MultiReferenceOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.MultiReferenceSetOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.OperationsFactory;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.ReferenceOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.SingleReferenceOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.UnsetType;

/**
 * Converts an EMF notification to an Operation.
 *
 * @author chodnick
 */
public final class NotificationToOperationConverter {

	private final IdEObjectCollectionImpl project;

	/**
	 * Default constructor.
	 *
	 * @param project
	 *            project
	 */
	public NotificationToOperationConverter(IdEObjectCollectionImpl project) {
		this.project = project;
	}

	/**
	 * Converts given notification to an operation. May return null if the
	 * notification signifies a no-op.
	 *
	 * @param n
	 *            the notification to convert
	 * @return the operation or null
	 */
	// BEGIN COMPLEX CODE
	public AbstractOperation convert(NotificationInfo n) {

		if (n.isTouch() || n.isTransient() || !n.isValid()) {
			return null;
		}

		switch (n.getEventType()) {

		case Notification.SET:
			if (n.isAttributeNotification()) {
				return handleSetAttribute(n);
			}
			return handleSetReference(n);

		case Notification.UNSET:
			if (n.isAttributeNotification()) {
				return handleUnsetAttribute(n);
			}
			return handleUnsetReference(n);

		case Notification.ADD:
			if (n.isAttributeNotification()) {
				return handleMultiAttribute(n);
			}
			return handleMultiReference(n);

		case Notification.ADD_MANY:
			if (n.isAttributeNotification()) {
				return handleMultiAttribute(n);
			}
			return handleMultiReference(n);

		case Notification.REMOVE:
			if (n.isAttributeNotification()) {
				return handleMultiAttribute(n);
			}
			return handleMultiReference(n);

		case Notification.REMOVE_MANY:
			if (n.isAttributeNotification()) {
				return handleMultiAttribute(n);
			}
			return handleMultiReference(n);

		case Notification.MOVE:
			if (n.isAttributeNotification()) {
				return handleAttributeMove(n);
			}
			return handleReferenceMove(n);

		default:
			return null;
		}
	}

	// END COMPLEX CODE

	@SuppressWarnings("unchecked")
	private AbstractOperation handleMultiAttribute(NotificationInfo n) {
		final MultiAttributeOperation operation = OperationsFactory.eINSTANCE.createMultiAttributeOperation();
		setCommonValues(project, operation, n.getNotifierModelElement());
		operation.setFeatureName(n.getAttribute().getName());
		operation.setAdd(n.isAddEvent() || n.isAddManyEvent());
		// operation.setIndex(n.getPosition());

		List<Object> list = null;

		switch (n.getEventType()) {

		case Notification.ADD:
			list = new ArrayList<Object>();
			operation.getIndexes().add(n.getPosition());
			list.add(n.getNewValue());
			break;
		case Notification.ADD_MANY:
			list = (List<Object>) n.getNewValue();
			for (int i = 0; i < list.size(); i++) {
				operation.getIndexes().add(n.getPosition() + i);
			}
			break;
		case Notification.REMOVE:
			list = new ArrayList<Object>();
			operation.getIndexes().add(n.getPosition());
			list.add(n.getOldValue());
			break;
		case Notification.REMOVE_MANY:
			list = (List<Object>) n.getOldValue();
			if (n.getNewValue() == null) {
				for (int i = 0; i < list.size(); i++) {
					operation.getIndexes().add(i);
				}
			} else {
				for (final int value : (int[]) n.getNewValue()) {
					operation.getIndexes().add(value);
				}
			}
			break;
		default:
			break;
		}

		if (list != null) {
			for (final Object valueElement : list) {
				operation.getReferencedValues().add(valueElement);
			}
		}

		if (n.wasUnset()) {
			operation.setUnset(UnsetType.WAS_UNSET);
		}

		return operation;
	}

	@SuppressWarnings("unchecked")
	private AbstractOperation handleMultiReference(NotificationInfo n) {

		List<EObject> list = new ArrayList<EObject>();

		switch (n.getEventType()) {
		case Notification.ADD:
			list.add(n.getNewModelElementValue());
			break;
		case Notification.ADD_MANY:
			list = (List<EObject>) n.getNewValue();
			break;
		case Notification.REMOVE:
			list.add(n.getOldModelElementValue());
			break;
		case Notification.REMOVE_MANY:
			list = (List<EObject>) n.getOldValue();
			break;
		default:
			break;
		}

		final boolean isAdd = n.isAddEvent() || n.isAddManyEvent();
		final MultiReferenceOperation multiRefOp = createMultiReferenceOperation(project, n.getNotifierModelElement(),
			n.getReference(), list, isAdd,
			n.getPosition());

		if (n.wasUnset()) {
			multiRefOp.setUnset(UnsetType.WAS_UNSET);
		}

		return multiRefOp;
	}

	/**
	 * Creates a multi reference operation based on the given information.
	 *
	 * @param collection
	 *            the collection the <code>modelElement</code> is contained in
	 * @param modelElement
	 *            the model element holding the reference
	 * @param reference
	 *            the actual reference
	 * @param referencedElements
	 *            the elements referenced by the reference
	 * @param isAdd
	 *            whether any referenced model elements were added to the <code>collection</code>
	 * @param position
	 *            the index of the model element within the <code>referenceElements</code> affected by
	 *            the generated operation
	 * @return a multi reference operation
	 */
	public static MultiReferenceOperation createMultiReferenceOperation(IdEObjectCollectionImpl collection,
		EObject modelElement, EReference reference, List<EObject> referencedElements, boolean isAdd, int position) {
		final MultiReferenceOperation op = OperationsFactory.eINSTANCE.createMultiReferenceOperation();
		setCommonValues(collection, op, modelElement);
		setBidirectionalAndContainmentInfo(op, reference);
		op.setFeatureName(reference.getName());
		op.setAdd(isAdd);
		op.setIndex(position);
		final List<ModelElementId> referencedModelElements = op.getReferencedModelElements();

		for (final EObject valueElement : referencedElements) {
			ModelElementId id = collection.getModelElementId(valueElement);
			if (id == null) {
				id = collection.getDeletedModelElementId(valueElement);
			}
			if (id != null) {
				referencedModelElements.add(id);
			} else if (ModelUtil.getProject(valueElement) == collection) {
				throw new IllegalStateException(
					Messages.NotificationToOperationConverter_Element_Has_No_ID + valueElement);
			}
			// ignore value elements outside of the current project, they are
			// not tracked
		}
		return op;

	}

	private AbstractOperation handleReferenceMove(NotificationInfo n) {

		final MultiReferenceMoveOperation op = OperationsFactory.eINSTANCE.createMultiReferenceMoveOperation();
		setCommonValues(project, op, n.getNotifierModelElement());
		op.setFeatureName(n.getReference().getName());
		op.setReferencedModelElementId(project.getModelElementId(n.getNewModelElementValue()));
		op.setNewIndex(n.getPosition());
		op.setOldIndex((Integer) n.getOldValue());

		return op;
	}

	private AbstractOperation handleAttributeMove(NotificationInfo n) {
		final MultiAttributeMoveOperation operation = OperationsFactory.eINSTANCE.createMultiAttributeMoveOperation();
		setCommonValues(project, operation, n.getNotifierModelElement());
		operation.setFeatureName(n.getAttribute().getName());
		operation.setNewIndex(n.getPosition());
		operation.setOldIndex((Integer) n.getOldValue());
		operation.setReferencedValue(n.getNewValue());
		return operation;
	}

	private AbstractOperation handleSetAttribute(NotificationInfo n) {

		if (!n.getAttribute().isMany()) {
			AttributeOperation op = null;
			// special handling for diagram layout changes
			op = OperationsFactory.eINSTANCE.createAttributeOperation();

			setCommonValues(project, op, n.getNotifierModelElement());
			op.setFeatureName(n.getAttribute().getName());
			op.setNewValue(n.getNewValue());
			op.setOldValue(n.getOldValue());

			if (n.wasUnset()) {
				op.setUnset(UnsetType.WAS_UNSET);
			}
			return op;
		}
		final MultiAttributeSetOperation setOperation = OperationsFactory.eINSTANCE
			.createMultiAttributeSetOperation();
		setCommonValues(project, setOperation, n.getNotifierModelElement());
		setOperation.setFeatureName(n.getAttribute().getName());
		setOperation.setNewValue(n.getNewValue());
		setOperation.setOldValue(n.getOldValue());
		setOperation.setIndex(n.getPosition());

		if (n.wasUnset()) {
			setOperation.setUnset(UnsetType.WAS_UNSET);
		}

		return setOperation;
	}

	/**
	 * Creates a single reference operation based on the given information.
	 *
	 * @param collection
	 *            the collection the <code>modelElement</code> is contained in
	 * @param oldReference
	 *            the {@link ModelElementId} of the model element the reference was pointing to
	 * @param newReference
	 *            the {@link ModelElementId} of the model element the reference is now pointing to
	 * @param reference
	 *            the actual reference
	 * @param modelElement
	 *            the model element holding the reference
	 * @return a single reference operation
	 */
	public static SingleReferenceOperation createSingleReferenceOperation(IdEObjectCollectionImpl collection,
		ModelElementId oldReference, ModelElementId newReference, EReference reference, EObject modelElement) {

		final SingleReferenceOperation op = OperationsFactory.eINSTANCE.createSingleReferenceOperation();
		setCommonValues(collection, op, modelElement);
		op.setFeatureName(reference.getName());
		setBidirectionalAndContainmentInfo(op, reference);

		op.setOldValue(oldReference);
		op.setNewValue(newReference);

		return op;
	}

	private AbstractOperation handleSetReference(NotificationInfo n) {

		ModelElementId oldModelElementId = project.getModelElementId(n.getOldModelElementValue());
		ModelElementId newModelElementId = project.getModelElementId(n.getNewModelElementValue());

		if (oldModelElementId == null) {
			oldModelElementId = ((ProjectImpl) project).getDeletedModelElementId(n.getOldModelElementValue());
		}

		if (newModelElementId == null) {
			newModelElementId = ((ProjectImpl) project).getDeletedModelElementId(n.getNewModelElementValue());
		}

		if (!n.getReference().isMany()) {
			final SingleReferenceOperation singleRefOperation = createSingleReferenceOperation(project,
				oldModelElementId,
				newModelElementId, n.getReference(),
				n.getNotifierModelElement());

			if (n.wasUnset()) {
				singleRefOperation.setUnset(UnsetType.WAS_UNSET);
			}

			return singleRefOperation;

		}
		final MultiReferenceSetOperation setOperation = OperationsFactory.eINSTANCE
			.createMultiReferenceSetOperation();
		setCommonValues(project, setOperation, (EObject) n.getNotifier());
		setOperation.setFeatureName(n.getReference().getName());
		setBidirectionalAndContainmentInfo(setOperation, n.getReference());

		setOperation.setIndex(n.getPosition());

		if (n.getOldValue() != null) {
			setOperation.setOldValue(oldModelElementId);
		}

		if (n.getNewValue() != null) {
			setOperation.setNewValue(newModelElementId);
		}

		if (n.wasUnset()) {
			setOperation.setUnset(UnsetType.WAS_UNSET);
		}

		return setOperation;
	}

	// utility methods
	private static void setCommonValues(IdEObjectCollectionImpl collection, AbstractOperation operation,
		EObject modelElement) {
		operation.setClientDate(new Date());
		ModelElementId id = collection.getModelElementId(modelElement);
		if (id == null) {
			id = collection.getDeletedModelElementId(modelElement);
		}
		if (id == null) {
			WorkspaceUtil.handleException(new IllegalStateException(
				Messages.NotificationToOperationConverter_Element_Has_No_ID
					+ modelElement));
		}
		operation.setModelElementId(id);
	}

	private static void setBidirectionalAndContainmentInfo(ReferenceOperation referenceOperation,
		EReference reference) {
		if (reference.getEOpposite() != null) {
			referenceOperation.setBidirectional(true);
			referenceOperation.setOppositeFeatureName(reference.getEOpposite().getName());
		} else {
			referenceOperation.setBidirectional(false);
		}
		if (reference.isContainer()) {
			referenceOperation.setContainmentType(ContainmentType.CONTAINER);
		}
		if (reference.isContainment()) {
			referenceOperation.setContainmentType(ContainmentType.CONTAINMENT);
		}
	}

	private AbstractOperation handleUnsetAttribute(NotificationInfo n) {
		final FeatureOperation op = (FeatureOperation) handleSetAttribute(n);
		op.setUnset(UnsetType.IS_UNSET);
		return op;
	}

	private AbstractOperation handleUnsetReference(NotificationInfo n) {
		FeatureOperation op;
		if (!n.getReference().isMany()) {
			op = (FeatureOperation) handleSetReference(n);
		} else {
			op = (FeatureOperation) handleMultiReference(n);
		}
		op.setUnset(UnsetType.IS_UNSET);
		return op;
	}

}
