/*******************************************************************************
 * 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.client.changetracking.test.canonization;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.List;

import org.eclipse.emf.emfstore.client.test.common.cases.ESTest;
import org.eclipse.emf.emfstore.client.test.common.dsl.Create;
import org.eclipse.emf.emfstore.internal.client.model.CompositeOperationHandle;
import org.eclipse.emf.emfstore.internal.client.model.exceptions.InvalidHandleException;
import org.eclipse.emf.emfstore.internal.client.model.util.EMFStoreCommand;
import org.eclipse.emf.emfstore.internal.common.model.Project;
import org.eclipse.emf.emfstore.internal.common.model.util.ModelUtil;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.AbstractOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.CompositeOperation;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.util.OperationsCanonizer;
import org.eclipse.emf.emfstore.test.model.TestElement;
import org.junit.Test;

/**
 * Tests canonization of composite operations.
 * 
 * @author chodnick
 */
public class CompositeTest extends ESTest {

	private static final String DESCRIPTION2 = "description"; //$NON-NLS-1$
	private static final String SECTION_CREATION = "sectionCreation"; //$NON-NLS-1$
	private static final String NEW_NAME = "newName"; //$NON-NLS-1$
	private static final String BLIBB = "blibb"; //$NON-NLS-1$
	private static final String BLUBB = "blubb"; //$NON-NLS-1$
	private static final String OLD_NAME = "oldName"; //$NON-NLS-1$
	private static final String OLD_DESCRIPTION = "oldDescription"; //$NON-NLS-1$
	private static final String C = "C"; //$NON-NLS-1$
	private static final String Y = "Y"; //$NON-NLS-1$
	private static final String B = "B"; //$NON-NLS-1$
	private static final String X = "X"; //$NON-NLS-1$
	private static final String A = "A"; //$NON-NLS-1$

	/**
	 * Tests canonization of empty composite operations.
	 * 
	 * @throws InvalidHandleException if an error occurrs
	 */
	@Test
	public void emptyComposite() throws InvalidHandleException {

		new EMFStoreCommand() {
			@Override
			protected void doRun() {
				// create an empty composite, should be canonized out
				final CompositeOperationHandle handle = getProjectSpace().beginCompositeOperation();
				try {
					handle.end(SECTION_CREATION, DESCRIPTION2, null);
				} catch (final InvalidHandleException e) {
					fail();
				}
			}
		}.run(false, getProjectSpace().getContentEditingDomain());

		final List<AbstractOperation> operations = getProjectSpace().getOperations();

		assertEquals(operations.size(), 1);

		new EMFStoreCommand() {
			@Override
			protected void doRun() {
				OperationsCanonizer.canonize(operations);
			}
		}.run(false, getProjectSpace().getContentEditingDomain());

		assertEquals(operations.size(), 0);

	}

	/**
	 * Tests canonization for consecutive attribute changes, resulting in a noop.
	 * 
	 * @throws InvalidHandleException if error occurs
	 */
	@Test
	public void noOpComposite() throws InvalidHandleException {

		final TestElement useCase = Create.testElement();

		new EMFStoreCommand() {
			@Override
			protected void doRun() {
				getProject().addModelElement(useCase);
				useCase.setName(OLD_NAME);
			}
		}.run(false, getProjectSpace().getContentEditingDomain());

		final Project expectedProject = ModelUtil.clone(getProject());
		assertTrue(ModelUtil.areEqual(getProject(), expectedProject));

		new EMFStoreCommand() {
			@Override
			protected void doRun() {
				clearOperations();

				final CompositeOperationHandle handle = getProjectSpace().beginCompositeOperation();

				useCase.setName(A);
				useCase.setName(B);
				useCase.setName(C);
				useCase.setName(OLD_NAME);

				assertEquals(OLD_NAME, useCase.getName());

				assertTrue(ModelUtil.areEqual(getProject(), expectedProject));

				try {
					handle.end(BLUBB, BLIBB, null);
				} catch (final InvalidHandleException e) {
					fail();
				}
			}
		}.run(false, getProjectSpace().getContentEditingDomain());

		final List<AbstractOperation> operations = getProjectSpace().getOperations();
		assertEquals(operations.size(), 1);

		new EMFStoreCommand() {
			@Override
			protected void doRun() {
				OperationsCanonizer.canonize(operations);
			}
		}.run(false, getProjectSpace().getContentEditingDomain());

		// should not have left any operations, we were just resetting the name to its original value
		assertEquals(operations.size(), 0);

	}

	/**
	 * Tests canonization for consecutive attribute changes, resulting in a noop.
	 * 
	 * @throws InvalidHandleException if error occurs
	 */
	@Test
	public void multiFeatureNoOpComposite() throws InvalidHandleException {

		final TestElement useCase = Create.testElement();

		new EMFStoreCommand() {
			@Override
			protected void doRun() {
				getProject().addModelElement(useCase);
				useCase.setName(OLD_NAME);
				useCase.setDescription(OLD_DESCRIPTION);
			}
		}.run(false, getProjectSpace().getContentEditingDomain());

		final Project expectedProject = ModelUtil.clone(getProject());
		assertTrue(ModelUtil.areEqual(getProject(), expectedProject));

		new EMFStoreCommand() {
			@Override
			protected void doRun() {
				clearOperations();

				final CompositeOperationHandle handle = getProjectSpace().beginCompositeOperation();

				useCase.setName(A);
				useCase.setDescription(X);
				useCase.setName(B);
				useCase.setDescription(Y);
				useCase.setName(C);

				useCase.setDescription(OLD_DESCRIPTION);
				useCase.setName(OLD_NAME);

				assertTrue(ModelUtil.areEqual(getProject(), expectedProject));

				try {
					handle.end(BLUBB, BLIBB, null);
				} catch (final InvalidHandleException e) {
					fail();
				}
			}
		}.run(false, getProjectSpace().getContentEditingDomain());

		final List<AbstractOperation> operations = getProjectSpace().getOperations();
		assertEquals(operations.size(), 1);

		new EMFStoreCommand() {
			@Override
			protected void doRun() {
				OperationsCanonizer.canonize(operations);
			}
		}.run(false, getProjectSpace().getContentEditingDomain());

		// should not have left any operations, we were just resetting the name to its original value
		assertEquals(operations.size(), 0);

	}

	/**
	 * Tests canonization for composite ops, where main operation might be canonized away.
	 * 
	 * @throws InvalidHandleException if error occurs
	 */
	@Test
	public void mainDeleteCompositeImplicitRestore() throws InvalidHandleException {

		final TestElement useCase = Create.testElement();

		new EMFStoreCommand() {
			@Override
			protected void doRun() {
				getProject().addModelElement(useCase);
				useCase.setName(OLD_NAME);
				clearOperations();

				final CompositeOperationHandle handle = getProjectSpace().beginCompositeOperation();

				useCase.setName(A);
				useCase.setName(B);
				useCase.setName(NEW_NAME);

				try {
					handle.end(BLUBB, BLIBB, null);
				} catch (final InvalidHandleException e) {
					fail();
				}
			}
		}.run(false, getProjectSpace().getContentEditingDomain());

		final List<AbstractOperation> operations = getProjectSpace().getOperations();
		assertEquals(operations.size(), 1);
		final CompositeOperation comp = (CompositeOperation) operations.get(0);

		new EMFStoreCommand() {
			@Override
			protected void doRun() {
				comp.setMainOperation(comp.getSubOperations().get(1)); // setName to from "A" to "B"
				OperationsCanonizer.canonize(operations);
			}
		}.run(false, getProjectSpace().getContentEditingDomain());

		// the main one was a candidate for removal, but since it is the main one, it may not be touched
		// in this case it will not even be modified
		assertTrue(comp.getSubOperations().contains(comp.getMainOperation()));
	}

	/**
	 * Tests canonization for composite ops, where main operation might be canonized away.
	 * 
	 * @throws InvalidHandleException if error occurs
	 */
	@Test
	public void mainDeleteCompositeImplicitMainOpModification() throws InvalidHandleException {

		final TestElement useCase = Create.testElement();

		new EMFStoreCommand() {
			@Override
			protected void doRun() {
				getProject().addModelElement(useCase);
				useCase.setName(OLD_NAME);

				clearOperations();

				final CompositeOperationHandle handle = getProjectSpace().beginCompositeOperation();

				useCase.setName(A);
				useCase.setName(B);
				useCase.setName(NEW_NAME);

				try {
					handle.end(BLUBB, BLIBB, null);
				} catch (final InvalidHandleException e) {
					fail();
				}
			}
		}.run(false, getProjectSpace().getContentEditingDomain());

		final List<AbstractOperation> operations = getProjectSpace().getOperations();
		assertEquals(operations.size(), 1);
		final CompositeOperation comp = (CompositeOperation) operations.get(0);

		new EMFStoreCommand() {
			@Override
			protected void doRun() {
				comp.setMainOperation(comp.getSubOperations().get(0)); // setName to from "oldName" to "A"
				OperationsCanonizer.canonize(operations);
			}
		}.run(false, getProjectSpace().getContentEditingDomain());

		// the main one was a candidate for removal, but since it is the main one, it may not be removed
		// it might have been altered though (newValue, oldValue etc., might have changed in the canonization
		// process)
		assertTrue(comp.getSubOperations().contains(comp.getMainOperation()));
	}

	/**
	 * Tests canonization for composite ops, where main operation might be canonized away.
	 * 
	 * @throws InvalidHandleException if error occurs
	 */
	@Test
	public void mainDeleteNoOpComposite() throws InvalidHandleException {

		final TestElement useCase = Create.testElement();

		new EMFStoreCommand() {
			@Override
			protected void doRun() {
				getProject().addModelElement(useCase);
				useCase.setName(OLD_NAME);

				clearOperations();

				final CompositeOperationHandle handle = getProjectSpace().beginCompositeOperation();

				useCase.setName(A);
				useCase.setName(B);
				useCase.setName(OLD_NAME);

				try {
					handle.end(BLUBB, BLIBB, null);
				} catch (final InvalidHandleException e) {
					fail();
				}
			}
		}.run(false, getProjectSpace().getContentEditingDomain());

		final List<AbstractOperation> operations = getProjectSpace().getOperations();
		assertEquals(operations.size(), 1);
		final CompositeOperation comp = (CompositeOperation) operations.get(0);
		new EMFStoreCommand() {
			@Override
			protected void doRun() {
				comp.setMainOperation(comp.getSubOperations().get(1)); // setName to from "A" to "B"
				OperationsCanonizer.canonize(operations);
			}
		}.run(false, getProjectSpace().getContentEditingDomain());
		// since this composite is a noop, everything should have been removed
		assertEquals(comp.getSubOperations().size(), 0);
	}

}
