/*
 * Copyright (c) 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();
  }

}
