/*******************************************************************************
 * Copyright (c) 2007, 2010 BMW Car IT, Technische Universitaet Muenchen, and others.
 * 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:
 * BMW Car IT - Initial API and implementation
 * Technische Universitaet Muenchen - Major refactoring and extension
 *******************************************************************************/
package org.eclipse.emf.edapt.history.reconstruction;

import java.util.HashSet;
import java.util.Set;

import org.eclipse.emf.ecore.EAttribute;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.ETypedElement;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.util.EcoreSwitch;
import org.eclipse.emf.edapt.internal.common.MetamodelExtent;
import org.eclipse.emf.edapt.internal.common.TypeUtils;
import org.eclipse.emf.edapt.spi.history.Change;
import org.eclipse.emf.edapt.spi.history.CompositeChange;
import org.eclipse.emf.edapt.spi.history.Create;
import org.eclipse.emf.edapt.spi.history.Delete;
import org.eclipse.emf.edapt.spi.history.InitializerChange;
import org.eclipse.emf.edapt.spi.history.MigrationChange;
import org.eclipse.emf.edapt.spi.history.Move;
import org.eclipse.emf.edapt.spi.history.OperationChange;
import org.eclipse.emf.edapt.spi.history.PrimitiveChange;
import org.eclipse.emf.edapt.spi.history.Release;
import org.eclipse.emf.edapt.spi.history.Remove;
import org.eclipse.emf.edapt.spi.history.util.HistorySwitch;

/**
 * A reconstructor that follows the history and checks whether changes are
 * breaking
 *
 * @author herrmama
 * @author $Author$
 * @version $Rev$
 * @levd.rating RED Rev:
 */
public class HistoryValidator extends ReconstructorBase {

	/**
	 * Switch to distinguish between different types of changes
	 */
	private ValidatorSwitch validatorSwitch;

	/**
	 * Mapping
	 */
	private Mapping mapping;

	/**
	 * Elements created within a certain period
	 */
	private final Set<EObject> createdElements;

	/**
	 * Whether current release is the first release
	 */
	private boolean inFirstRelease;

	/**
	 * Whether reconstruction currently is inside a migration change
	 */
	private boolean inMigrationChange;

	/**
	 * Whether reconstruction currently is inside an operation change
	 */
	private boolean inOperationChange;

	/**
	 * Whether reconstruction currently is inside an initializer change
	 */
	private boolean inInitializerChange;

	/**
	 * Default constructor
	 *
	 */
	public HistoryValidator() {
		createdElements = new HashSet<EObject>();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void init(Mapping mapping, MetamodelExtent extent) {
		this.mapping = mapping;
		validatorSwitch = new ValidatorSwitch();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void startRelease(Release originalRelease) {
		inFirstRelease = originalRelease.isFirstRelease();
		reset();
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void startChange(Change originalChange) {

		if (canIgnore()) {
			originalChange.setBreaking(false);
			return;
		}

		originalChange.setBreaking(validatorSwitch.doSwitch(originalChange));

		startIgnore(originalChange);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void endChange(Change change) {

		endIgnore(change);

		if (canIgnore()) {
			return;
		}

		endUpdate(change);
	}

	/**
	 * Check whether the current change can be ignored
	 */
	private boolean canIgnore() {
		return inFirstRelease || inMigrationChange || inOperationChange
			|| inInitializerChange;
	}

	/**
	 * Set ignore status when starting a change
	 */
	private void startIgnore(Change change) {
		if (change instanceof MigrationChange) {
			inMigrationChange = true;
			change.setBreaking(false);
			reset();
		} else if (change instanceof OperationChange) {
			inOperationChange = true;
			change.setBreaking(false);
			reset();
		} else if (change instanceof InitializerChange) {
			inInitializerChange = true;
			change.setBreaking(false);
		}
	}

	/**
	 * Unset ignore status when ending a change
	 */
	private void endIgnore(Change change) {
		if (change instanceof MigrationChange) {
			inMigrationChange = false;
			reset();
		} else if (change instanceof OperationChange) {
			inOperationChange = false;
			reset();
		} else if (change instanceof InitializerChange) {
			inInitializerChange = false;
		}
	}

	/**
	 * Perform updates when ending a change
	 */
	private void endUpdate(Change change) {
		if (change instanceof Create) {
			// add created element
			final Create createChild = (Create) change;
			final EObject created = mapping.resolveTarget(createChild.getElement());
			created(created);
		} else if (change instanceof CompositeChange
			&& !(change instanceof OperationChange)) {
			// update breaking status of composite change
			final CompositeChange compositeChange = (CompositeChange) change;
			boolean breaking = false;
			for (final PrimitiveChange primitiveChange : compositeChange.getChanges()) {
				breaking |= primitiveChange.isBreaking();
			}
			compositeChange.setBreaking(breaking);
			reset();
		}
	}

	/**
	 * Register a created element
	 */
	private void created(EObject element) {
		createdElements.add(element);
	}

	/**
	 * Check whether an element was recently created
	 *
	 * @param element
	 *            Element
	 * @return true if the element was recently created, false otherwise
	 */
	private boolean isCreated(EObject element) {
		return createdElements.contains(element);
	}

	/**
	 * Reset the registry of recently created elements
	 */
	private void reset() {
		createdElements.clear();
	}

	/**
	 * Switch to distinguish between different types of changes
	 */
	private class ValidatorSwitch extends HistorySwitch<Boolean> {

		/**
		 * Ecore package
		 */
		private final EcorePackage p = EcorePackage.eINSTANCE;

		/**
		 * {@inheritDoc}
		 */
		@Override
		public Boolean caseSet(final org.eclipse.emf.edapt.spi.history.Set set) {
			final EStructuralFeature feature = set.getFeature();
			final EObject element = mapping.resolveTarget(set.getElement());
			if (isCreated(element)) {
				return false;
			}

			/**
			 * Switch distinguish element types
			 */
			final EcoreSwitch<Boolean> setValidatorSwitch = new EcoreSwitch<Boolean>() {
				@Override
				public Boolean caseETypedElement(ETypedElement object) {

					if (object instanceof EOperation) {
						return false;
					} else if (object instanceof EStructuralFeature
						&& feature.isDerived()) {
						return false;
					}

					switch (feature.getFeatureID()) {
					// ETypedElement.unique -> true
					case EcorePackage.ETYPED_ELEMENT__UNIQUE: {
						final boolean value = (Boolean) set.getValue();
						if (value) {
							return true;
						}
						break;
					}
					// ETypedElement.upperBound
					case EcorePackage.ETYPED_ELEMENT__UPPER_BOUND: {
						final int value = (Integer) set.getValue();
						final int oldValue = (Integer) set.getOldValue();
						// decrease
						if (oldValue < 0) {
							return true;
						} else if (value >= 0 && value < oldValue) {
							return true;
						}
						break;
					}
					// ETypedElement.eType
					case EcorePackage.ETYPED_ELEMENT__ETYPE: {
						if (set.getElement() instanceof EReference) {
							final EClass oldValue = (EClass) mapping
								.resolveTarget(set.getOldValue());
							final EClass newValue = (EClass) mapping.resolveTarget(set
								.getValue());
							if (!TypeUtils.ancestor(oldValue, newValue)) {
								return true;
							}
						} else {
							return true;
						}
						break;
					}
					}

					return null;
				}

				@Override
				public Boolean caseEStructuralFeature(EStructuralFeature object) {
					switch (feature.getFeatureID()) {
					// EStructuralFeature.transient -> true
					case EcorePackage.ESTRUCTURAL_FEATURE__TRANSIENT: {
						final boolean value = (Boolean) set.getValue();
						if (value) {
							return true;
						}
						break;
					}
					}

					return null;
				}

				@Override
				public Boolean caseEAttribute(EAttribute object) {
					switch (feature.getFeatureID()) {
					// EAttribute.iD -> true
					case EcorePackage.EATTRIBUTE__ID: {
						final boolean value = (Boolean) set.getValue();
						if (value) {
							return true;
						}
						break;
					}
					}

					return null;
				}

				@Override
				public Boolean caseEReference(EReference object) {
					switch (feature.getFeatureID()) {
					// EReference.containment
					case EcorePackage.EREFERENCE__CONTAINMENT: {
						return true;
					}
					// EReference.eOpposite
					case EcorePackage.EREFERENCE__EOPPOSITE: {
						return true;
					}
					}

					return null;
				}

				@Override
				public Boolean caseEClass(EClass eClass) {
					switch (feature.getFeatureID()) {
					case EcorePackage.ECLASS__ABSTRACT: {
						// EClass.abstract -> true
						if (feature == p.getEClass_Abstract()) {
							final boolean value = (Boolean) set.getValue();
							if (value && !eClass.isInterface()) {
								return true;
							}
						}
						break;
					}
					// EClass.interface -> true
					case EcorePackage.ECLASS__INTERFACE: {
						final boolean value = (Boolean) set.getValue();
						if (value && !eClass.isAbstract()) {
							return true;
						}
						break;
					}
					}

					return null;
				}

				@Override
				public Boolean defaultCase(EObject object) {
					return false;
				}
			};

			return setValidatorSwitch.doSwitch(element);
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public Boolean caseRemove(Remove remove) {
			final EStructuralFeature feature = remove.getFeature();
			final EObject element = mapping.resolveTarget(remove.getElement());
			if (isCreated(element)) {
				return false;
			}

			// EClass.eSuperTypes
			if (element instanceof EClass) {
				switch (feature.getFeatureID()) {
				case EcorePackage.ECLASS__ESUPER_TYPES:
					final EClass eClass = (EClass) remove.getValue();
					if (!eClass.getEAllStructuralFeatures().isEmpty()) {
						return true;
					}
					break;
				}
			}

			return false;
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public Boolean caseDelete(Delete delete) {
			final EObject element = mapping.resolveTarget(delete.getElement());
			if (isCreated(element)) {
				return false;
			}

			if (element instanceof EStructuralFeature) {
				return true;
			} else if (!delete.getChanges().isEmpty()) {
				return true;
			}

			return false;
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public Boolean caseMove(Move move) {
			final EObject element = move.getElement();
			if (element instanceof EStructuralFeature) {
				return true;
			}

			return false;
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public Boolean defaultCase(EObject object) {
			return false;
		}
	}
}
