/*
 * Copyright (c) 2004 - 2014 Eike Stepper (Berlin, Germany) 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:
 *    Eike Stepper - initial API and implementation
 */
package org.eclipse.emf.cdo.tests.bugzilla;

import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.tests.model6.ContainmentObject;
import org.eclipse.emf.cdo.transaction.CDOTransaction;

import org.eclipse.emf.ecore.resource.Resource;

import org.junit.Assert;

import java.util.Collections;

/**
 * @author Esteban Dugueperoux
 * 
 * Test about remote detachment.
 */
public class Bugzilla_363355_Test extends AbstractCDOTest
{
  private static final String RESOURCE_PATH = "/test1";

  private CDOSession sessionOfUser1;

  private CDOTransaction transactionOfUser1;

  private ContainmentObject co1;

  private ContainmentObject co2;

  private ContainmentObject co3;

  @Override
  public void setUp() throws Exception
  {
    super.setUp();
    sessionOfUser1 = openSession();
    transactionOfUser1 = sessionOfUser1.openTransaction();
    CDOResource resourceOfUser1 = transactionOfUser1.createResource(getResourcePath(RESOURCE_PATH));

    co1 = getModel6Factory().createContainmentObject();

    co2 = getModel6Factory().createContainmentObject();
    co1.setContainmentOptional(co2);

    co3 = getModel6Factory().createContainmentObject();
    co2.setContainmentOptional(co3);

    resourceOfUser1.getContents().add(co1);
    resourceOfUser1.save(Collections.emptyMap());
  }

  /**
   * Test about remotely detached object make CDOTransaction dirty
   * in invalidation while it shouldn't.
   *
   * @throws Exception
   */
  public void testCDOTransactionDirtyOnInvalidation() throws Exception
  {
    // User 2 do changes
    CDOSession sessionOfUser2 = openSession();
    CDOTransaction transactionOfUser2 = sessionOfUser2.openTransaction();
    transactionOfUser2.options().setAutoReleaseLocksEnabled(false);

    Resource resourceOfUser2 = transactionOfUser2.getResource(getResourcePath(RESOURCE_PATH));
    ContainmentObject co1_OfUser2 = (ContainmentObject)resourceOfUser2.getContents().get(0);

    ContainmentObject co2_OfUser2 = (ContainmentObject)co1_OfUser2.getContainmentOptional();

    ContainmentObject newCO3FromUser2 = getModel6Factory().createContainmentObject();
    co2_OfUser2.setContainmentOptional(newCO3FromUser2);

    commitAndSync(transactionOfUser2, transactionOfUser1);

    // User 1 checks that its transaction is not dirty
    Assert.assertFalse("Receiving remote changes shouldn't set local CDOTransaction dirty",
        transactionOfUser1.isDirty());

    commitAndSync(transactionOfUser1, transactionOfUser2);

    transactionOfUser2.close();
    sessionOfUser2.close();
  }

  /**
   * Because we have found a scenario for which the initial
   * fix, i.e. manage detached objects before changed objects in invalidation,
   * cause a regression "Cannot modify a frozen revisison" in invalidation in
   * legacy.
   * <p>
   * Scenario :
   * <ol>
   * <li>User1 have a ContainmentObject co1 containing a ContainmentObject co2 and this last contains a ContainmentObject co3</li>
   * <li>User1 set a new co2 having a its own co3 to co1 and move
   * the original co3 of the old co2 to the new co2 and commit</li>
   * <li>User2 get a "Cannot modify a frozen revision" exception in
   * invalidation</li>
   * </ol>
   * </p>
   *
   * @throws Exception
   */
  public void testCannotModifyFrozenRevisionOnInvalidation() throws Exception
  {
    // User 2 do changes
    CDOSession sessionOfUser2 = openSession();
    CDOTransaction transactionOfUser2 = sessionOfUser2.openTransaction();
    transactionOfUser2.options().setAutoReleaseLocksEnabled(false);

    Resource resourceOfUser2 = transactionOfUser2.getResource(getResourcePath(RESOURCE_PATH));
    ContainmentObject co1_OfUser2 = (ContainmentObject)resourceOfUser2.getContents().get(0);
    ContainmentObject co2_OfUser2 = (ContainmentObject)co1_OfUser2.getContainmentOptional();
    co2_OfUser2.getContainmentOptional();

    ContainmentObject newCO2 = getModel6Factory().createContainmentObject();
    ContainmentObject newCO3 = getModel6Factory().createContainmentObject();
    newCO2.setContainmentOptional(newCO3);
    co1_OfUser2.setContainmentOptional(newCO2);

    ContainmentObject oldCO3 = (ContainmentObject)co2_OfUser2.getContainmentOptional();
    newCO2.setContainmentOptional(oldCO3);

    commitAndSync(transactionOfUser2, transactionOfUser1);

    // Asserts on user1 transaction, receiving the changes committed by
    // user2
    Assert.assertNotSame(co2, co3.eContainer());
    Assert.assertSame(co1.getContainmentOptional(), co3.eContainer());
    Assert.assertNull(co2.eContainer());
    Assert.assertFalse("Receiving remote changes shouldn't set local CDOTransaction dirty",
        transactionOfUser2.isDirty());

    transactionOfUser2.close();
    sessionOfUser2.close();
  }

  @Override
  public void tearDown() throws Exception
  {
    transactionOfUser1.close();
    transactionOfUser1 = null;
    sessionOfUser1.close();
    sessionOfUser1 = null;
    co1 = null;
    co2 = null;
    co3 = null;
    super.tearDown();
  }

}
