/*******************************************************************************
 * 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.conflictdetection.test;

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

import java.util.List;

import org.eclipse.emf.emfstore.client.test.common.dsl.Add;
import org.eclipse.emf.emfstore.client.test.common.dsl.Create;
import org.eclipse.emf.emfstore.internal.client.model.ProjectSpace;
import org.eclipse.emf.emfstore.internal.client.model.util.EMFStoreCommand;
import org.eclipse.emf.emfstore.internal.common.model.ModelElementId;
import org.eclipse.emf.emfstore.internal.common.model.Project;
import org.eclipse.emf.emfstore.internal.server.conflictDetection.ConflictBucket;
import org.eclipse.emf.emfstore.internal.server.model.versioning.operations.AbstractOperation;
import org.eclipse.emf.emfstore.test.model.TestElement;
import org.junit.Test;

/**
 * Tests conflict detection behaviour on attributes.
 *
 * @author chodnick
 */
public class ConflictDetectionDeleteTest extends ConflictDetectionTest {

	private static final String CHANGE_TO_UNRELATED_OBJECT_ON_ANOTHER_WORKING_COPY = "change to unrelated object on another working copy"; //$NON-NLS-1$
	private static final String CHANGE_TO_OBJECT_INSIDE_DELTREE_ON_ANOTHER_WORKING_COPY = "change to object inside deltree on another working copy"; //$NON-NLS-1$
	private static final String CHANGE_TO_THE_DELETED_OBJECT_ON_ANOTHER_WORKING_COPY = "change to the deleted object on another working copy"; //$NON-NLS-1$
	private static final String OLD_NAME = "old name"; //$NON-NLS-1$

	/**
	 * Tests if deleting an object is detected as conflict.
	 */
	@Test
	public void conflictDelete() {

		final TestElement section = Create.testElement();
		final TestElement actor = Create.testElement();
		actor.setName(OLD_NAME);

		Add.toProject(getLocalProject(), section);
		Add.toContainedElements(section, actor);
		clearOperations();

		final ProjectSpace ps2 = cloneProjectSpace(getProjectSpace());
		final Project project2 = ps2.getProject();

		final ModelElementId actorId = getProject().getModelElementId(actor);

		final TestElement actor1 = (TestElement) getProject().getModelElement(actorId);
		final TestElement actor2 = (TestElement) project2.getModelElement(actorId);

		new EMFStoreCommand() {

			@Override
			protected void doRun() {
				getProject().deleteModelElement(actor1);
				actor2.setName(CHANGE_TO_THE_DELETED_OBJECT_ON_ANOTHER_WORKING_COPY);
			}
		}.run(false);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(ps2);

		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2);

		final ConflictBucket bucket = conflicts.get(0);
		assertEquals(1, bucket.getMyOperations().size());
		assertEquals(1, bucket.getTheirOperations().size());

		assertEquals(conflicts.size(), 1);

	}

	/**
	 * Tests if deleting an object is detected as conflict.
	 */
	@Test
	public void conflictDeleteAttributeChangesInDeltree() {

		final TestElement section = Create.testElement();
		final TestElement actor = Create.testElement();
		actor.setName(OLD_NAME);
		new EMFStoreCommand() {

			@Override
			protected void doRun() {
				getProject().addModelElement(section);
				section.getContainedElements().add(actor);
				clearOperations();

			}
		}.run(false);

		final ProjectSpace ps2 = cloneProjectSpace(getProjectSpace());
		final Project project2 = ps2.getProject();

		final ModelElementId section1Id = getProject().getModelElementId(section);
		final ModelElementId actorId = getProject().getModelElementId(actor);

		final TestElement section1 = (TestElement) getProject().getModelElement(section1Id);
		final TestElement actor2 = (TestElement) project2.getModelElement(actorId);
		new EMFStoreCommand() {

			@Override
			protected void doRun() {
				getProject().deleteModelElement(section1);
				actor2.setName(CHANGE_TO_OBJECT_INSIDE_DELTREE_ON_ANOTHER_WORKING_COPY);

			}
		}.run(false);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(ps2);

		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2);
		final ConflictBucket bucket = conflicts.get(0);

		assertEquals(1, bucket.getMyOperations().size());
		assertEquals(1, bucket.getTheirOperations().size());
		assertEquals(conflicts.size(), 1);
	}

	/**
	 * Tests if deleting an object is detected as conflict.
	 */
	@Test
	public void conflictDeleteAttributeChangesInDelObject() {

		final TestElement section = Create.testElement();
		new EMFStoreCommand() {

			@Override
			protected void doRun() {
				getProject().addModelElement(section);
				clearOperations();

			}
		}.run(false);

		final ProjectSpace ps2 = cloneProjectSpace(getProjectSpace());
		final Project project2 = ps2.getProject();

		final ModelElementId sectionId = getProject().getModelElementId(section);

		final TestElement section1 = (TestElement) getProject().getModelElement(sectionId);
		final TestElement section2 = (TestElement) project2.getModelElement(sectionId);
		new EMFStoreCommand() {

			@Override
			protected void doRun() {
				getProject().deleteModelElement(section1);
				section2.setName(CHANGE_TO_OBJECT_INSIDE_DELTREE_ON_ANOTHER_WORKING_COPY);

			}
		}.run(false);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(ps2);

		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2);
		final ConflictBucket bucket = conflicts.get(0);

		assertEquals(1, bucket.getMyOperations().size());
		assertEquals(1, bucket.getTheirOperations().size());
		assertEquals(conflicts.size(), 1);

	}

	/**
	 * Tests if deleting an object is detected as conflict.
	 */
	@Test
	public void noConflictDeleteUnrelated() {

		final TestElement section = Create.testElement();
		final TestElement actor = Create.testElement();
		new EMFStoreCommand() {

			@Override
			protected void doRun() {
				getProject().addModelElement(section);
				getProject().addModelElement(actor);
				clearOperations();

			}
		}.run(false);

		final ProjectSpace ps2 = cloneProjectSpace(getProjectSpace());
		final Project clonedProject = ps2.getProject();

		final ModelElementId actorId = getProject().getModelElementId(actor);
		final ModelElementId sectionId = getProject().getModelElementId(section);

		final TestElement actor1 = (TestElement) getProject().getModelElement(actorId);
		final TestElement clonedSection = (TestElement) clonedProject.getModelElement(sectionId);
		new EMFStoreCommand() {

			@Override
			protected void doRun() {
				actor1.setName(CHANGE_TO_UNRELATED_OBJECT_ON_ANOTHER_WORKING_COPY);
				clonedProject.deleteModelElement(clonedSection);

			}
		}.run(false);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(ps2);

		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2);
		assertTrue(conflicts.isEmpty());
	}

	/**
	 * Tests if deleting an object is detected as conflict.
	 */
	@Test
	public void conflictDeleteContainmentChangesInDeltree() {

		final TestElement section = Create.testElement();
		final TestElement pack = Create.testElement();
		final TestElement br = Create.testElement();
		new EMFStoreCommand() {

			@Override
			protected void doRun() {
				getProject().addModelElement(section);
				getProject().addModelElement(pack);
				getProject().addModelElement(br);
				section.getContainedElements().add(pack);
				clearOperations();
			}
		}.run(false);

		final ProjectSpace ps2 = cloneProjectSpace(getProjectSpace());
		final Project project2 = ps2.getProject();

		final ModelElementId brId = getProject().getModelElementId(br);
		final ModelElementId packId = getProject().getModelElementId(pack);
		final ModelElementId sectionId = getProject().getModelElementId(section);

		final TestElement br1 = (TestElement) getProject().getModelElement(brId);
		final TestElement pack1 = (TestElement) getProject().getModelElement(packId);
		final TestElement section2 = (TestElement) project2.getModelElement(sectionId);
		new EMFStoreCommand() {

			@Override
			protected void doRun() {
				br1.setContainer(pack1);
				project2.deleteModelElement(section2);

			}
		}.run(false);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(ps2);

		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2);
		final ConflictBucket bucket = conflicts.get(0);

		assertEquals(1, bucket.getMyOperations().size());
		assertEquals(1, bucket.getTheirOperations().size());
		assertEquals(conflicts.size(), 1);

	}

	/**
	 * Tests if deleting an object is detected as conflict.
	 */
	@Test
	public void conflictDeleteNonContainmentChangesInDeltree() {

		final TestElement section = Create.testElement();
		final TestElement useCase = Create.testElement();
		final TestElement mileStone = Create.testElement();
		new EMFStoreCommand() {

			@Override
			protected void doRun() {
				getProject().addModelElement(section);
				getProject().addModelElement(useCase);
				getProject().addModelElement(mileStone);
				section.getContainedElements().add(useCase);
				clearOperations();
			}
		}.run(false);

		final ProjectSpace ps2 = cloneProjectSpace(getProjectSpace());
		final Project project2 = ps2.getProject();

		final ModelElementId mileStoneId = getProject().getModelElementId(mileStone);
		final ModelElementId useCaseId = getProject().getModelElementId(useCase);
		final ModelElementId sectionId = getProject().getModelElementId(section);

		final TestElement mileStone1 = (TestElement) getProject().getModelElement(mileStoneId);
		final TestElement useCase1 = (TestElement) getProject().getModelElement(useCaseId);
		final TestElement section2 = (TestElement) project2.getModelElement(sectionId);
		new EMFStoreCommand() {

			@Override
			protected void doRun() {
				useCase1.getContainedElements().add(mileStone1);
				project2.deleteModelElement(section2);

			}
		}.run(false);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(ps2);

		// technically no conflict, since annotated milestone will not be deleted,
		// but there is no way to tell containment from non-containment changes,
		// therefore it is expected that this will be detected as a hard conflict
		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2);
		assertEquals(conflicts.size(), 1);
		final ConflictBucket bucket = conflicts.get(0);

		assertEquals(1, bucket.getMyOperations().size());
		assertEquals(1, bucket.getTheirOperations().size());
		assertEquals(conflicts.size(), 1);
	}

	/**
	 * Tests if deleting an object is detected as conflict.
	 */
	@Test
	public void conflictDeleteMoveChangesInDeltree() {

		final TestElement section = Create.testElement();
		final TestElement pack = Create.testElement();
		final TestElement br1 = Create.testElement();
		final TestElement br2 = Create.testElement();
		new EMFStoreCommand() {

			@Override
			protected void doRun() {
				getProject().addModelElement(section);
				getProject().addModelElement(pack);
				getProject().addModelElement(br1);

				br1.setContainer(pack);
				br2.setContainer(pack);

			}
		}.run(false);

		assertEquals(pack.getContainedElements().get(0), br1);
		assertEquals(pack.getContainedElements().get(1), br2);

		new EMFStoreCommand() {
			@Override
			protected void doRun() {
				section.getContainedElements().add(pack);
				clearOperations();
			}
		}.run(false);

		final ProjectSpace ps2 = cloneProjectSpace(getProjectSpace());
		final Project project2 = ps2.getProject();

		final ModelElementId packId = getProject().getModelElementId(pack);
		final ModelElementId sectionId = getProject().getModelElementId(section);

		final TestElement pack1 = (TestElement) getProject().getModelElement(packId);
		final TestElement section2 = (TestElement) project2.getModelElement(sectionId);

		new EMFStoreCommand() {

			@Override
			protected void doRun() {
				pack1.getContainedElements().move(1, 0);
				project2.deleteModelElement(section2);

			}
		}.run(false);

		final List<AbstractOperation> ops1 = forceGetOperations();
		final List<AbstractOperation> ops2 = forceGetOperations(ps2);

		// a move change is a change... from users perspective it should not be lost, probably..
		// currently considered to be a hard conflict, because the user should know
		final List<ConflictBucket> conflicts = getConflicts(ops1, ops2);
		assertEquals(conflicts.size(), 1);
		final ConflictBucket bucket = conflicts.get(0);

		assertEquals(1, bucket.getMyOperations().size());
		assertEquals(1, bucket.getTheirOperations().size());
		assertEquals(conflicts.size(), 1);

	}
}
