/*
 * Copyright (c) 2010-2013, 2015 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.common.id.CDOID;
import org.eclipse.emf.cdo.common.revision.delta.CDOFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDOListFeatureDelta;
import org.eclipse.emf.cdo.common.revision.delta.CDORevisionDelta;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.server.IRepository.WriteAccessHandler;
import org.eclipse.emf.cdo.server.IStoreAccessor.CommitContext;
import org.eclipse.emf.cdo.server.ITransaction;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.spi.common.revision.InternalCDORevisionDelta;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.tests.model3.NodeA;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.view.CDOView;

import org.eclipse.net4j.util.om.monitor.OMMonitor;

import org.eclipse.emf.edit.command.DragAndDropCommand;

import java.text.MessageFormat;

/**
 * Moving nodes in a tree structure (simulate a {@link DragAndDropCommand}) may result in an inconsistent tree.
 * <p>
 * See bug 319836
 *
 * @author Cyril Jaquier
 */
public class Bugzilla_319836_Test extends AbstractCDOTest
{
  private static final boolean SHOW_BUG = true;

  public void testNodeMovesInTreeCreatesCycle() throws Exception
  {
    {
      // Setup an initial session and a transaction.
      CDOSession session = openSession();
      CDOTransaction tr1 = session.openTransaction();
      CDOResource resource = tr1.createResource(getResourcePath("/test1"));

      NodeA n1 = getModel3Factory().createNodeA();
      NodeA n2 = getModel3Factory().createNodeA();
      NodeA n3 = getModel3Factory().createNodeA();

      resource.getContents().add(n1);

      // Create a deep tree.
      //
      // n1
      // `- n2
      // ___`- n3
      n1.getChildren().add(n2);
      n2.getChildren().add(n3);

      tr1.commit();
      setNames(n1, n2, n3);
      tr1.commit();
      addCommitContextTracer();

      // First move.
      //
      // n1
      // |- n2
      // `- n3
      if (SHOW_BUG)
      {
        n2.getChildren().remove(n3);
      }

      n1.getChildren().add(n3);

      // Second move.
      //
      // n1
      // `- n3
      // ___`- n2

      // Something bad will happen during the execution of the next line. Set a breakpoint in
      // org.eclipse.emf.internal.cdo.transaction.CDOSavepointImpl.detachedObjects.new Map<CDOID, CDOObject>()
      // {...}.put(CDOID, CDOObject) and see how the previous REMOVE is eaten.
      if (SHOW_BUG)
      {
        n1.getChildren().remove(n2);
      }

      n3.getChildren().add(n2);

      // Problem is with n2; the removal of its child has been lost
      CDOID n2ID = CDOUtil.getCDOObject(n2).cdoID();
      CDORevisionDelta revDelta = tr1.getRevisionDeltas().get(n2ID);
      assertEquals(2, revDelta.getFeatureDeltas().size());

      tr1.commit();

      // Checks the tree.
      assertEquals(1, n1.getChildren().size());
      assertEquals(0, n2.getChildren().size());
      assertEquals(1, n3.getChildren().size());
    }

    {
      // Setup a new session. The bug only does not seem to occur if we use the same session.
      CDOSession session = openSession();
      CDOView view = session.openView();
      CDOResource resource = view.getResource(getResourcePath("/test1"));

      NodeA n1 = (NodeA)resource.getContents().get(0);

      // Checks the tree.
      assertEquals(1, n1.getChildren().size());
      NodeA n3 = n1.getChildren().get(0);
      assertEquals(1, n3.getChildren().size());
      NodeA n2 = n3.getChildren().get(0);
      // Oups... n2 has a child!? And even worst... it's n3 :'( Houston, we have a problem...
      assertEquals(0, n2.getChildren().size());
    }
  }

  public void testNodeMovesInTreeDuplicatesNode() throws Exception
  {
    {
      // Setup an initial session and a transaction.
      CDOSession session = openSession();
      CDOTransaction tr1 = session.openTransaction();
      CDOResource resource = tr1.createResource(getResourcePath("/test1"));

      NodeA n1 = getModel3Factory().createNodeA();
      NodeA n2 = getModel3Factory().createNodeA();
      NodeA n3 = getModel3Factory().createNodeA();
      NodeA n4 = getModel3Factory().createNodeA();

      resource.getContents().add(n1);

      // Create a deep tree.
      //
      // n1
      // `- n2
      // ___`- n3
      // ______`- n4
      n1.getChildren().add(n2);
      n2.getChildren().add(n3);
      n3.getChildren().add(n4);

      tr1.commit();
      setNames(n1, n2, n3);
      tr1.commit();
      addCommitContextTracer();

      // First move.
      //
      // n1
      // `- n2
      // ___|- n3
      // ___`- n4
      if (SHOW_BUG)
      {
        n3.getChildren().remove(n4);
      }

      n2.getChildren().add(n4);

      // Second move.
      //
      // n1
      // |- n2
      // |__`- n4
      // `- n3

      // Something bad will happen during the execution of the next line. Set a breakpoint in
      // org.eclipse.emf.internal.cdo.transaction.CDOSavepointImpl.detachedObjects.new Map<CDOID, CDOObject>()
      // {...}.put(CDOID, CDOObject) and see how the previous REMOVE is eaten.
      if (SHOW_BUG)
      {
        n2.getChildren().remove(n3);
      }

      n1.getChildren().add(n3);

      tr1.commit();

      // Checks the tree.
      assertEquals(2, n1.getChildren().size());
      assertEquals(1, n2.getChildren().size());
      assertEquals(0, n3.getChildren().size());
      assertEquals(0, n4.getChildren().size());
    }

    {
      // Setup a new session. The bug only does not seem to occur if we use the same session.
      CDOSession session = openSession();
      CDOView view = session.openView();
      CDOResource resource = view.getResource(getResourcePath("/test1"));

      NodeA n1 = (NodeA)resource.getContents().get(0);

      // Checks the tree.
      assertEquals(2, n1.getChildren().size());
      NodeA n2 = n1.getChildren().get(0);
      assertEquals(1, n2.getChildren().size());
      NodeA n4 = n2.getChildren().get(0);
      assertEquals(0, n4.getChildren().size());
      NodeA n3 = n1.getChildren().get(1);
      // Oups... n3 has a child!?
      assertEquals(0, n3.getChildren().size());
    }
  }

  public void testNodeMovesInTreeEatsNode() throws Exception
  {
    {
      // Setup an initial session and a transaction.
      CDOSession session = openSession();
      CDOTransaction tr1 = session.openTransaction();
      CDOResource resource = tr1.createResource(getResourcePath("/test1"));

      NodeA n1 = getModel3Factory().createNodeA();
      NodeA n2 = getModel3Factory().createNodeA();
      NodeA n3 = getModel3Factory().createNodeA();
      NodeA n4 = getModel3Factory().createNodeA();

      resource.getContents().add(n1);

      // Create a flat tree.
      //
      // n1
      // |- n2
      // |- n3
      // `- n4
      n1.getChildren().add(n2);
      n1.getChildren().add(n3);
      n1.getChildren().add(n4);

      tr1.commit();
      setNames(n1, n2, n3);
      tr1.commit();
      addCommitContextTracer();

      // First move.
      //
      // n1
      // |- n2
      // `- n3
      // ___`- n4
      if (SHOW_BUG)
      {
        n1.getChildren().remove(n4);
      }

      n3.getChildren().add(n4);

      // Second move.
      //
      // n1
      // `- n2
      // ___`- n3
      // ______`- n4

      // Something bad will happen during the execution of the next line. Set a breakpoint in
      // org.eclipse.emf.internal.cdo.transaction.CDOSavepointImpl.detachedObjects.new Map<CDOID, CDOObject>()
      // {...}.put(CDOID, CDOObject) and see how the previous ADD is eaten.
      if (SHOW_BUG)
      {
        n1.getChildren().remove(n3);
      }

      n2.getChildren().add(n3);

      tr1.commit();

      // Checks the tree.
      assertEquals(1, n1.getChildren().size());
      assertEquals(n2, n1.getChildren().get(0));
      assertEquals(1, n2.getChildren().size());
      assertEquals(n3, n2.getChildren().get(0));
      assertEquals(1, n3.getChildren().size());
      assertEquals(n4, n3.getChildren().get(0));
      assertEquals(0, n4.getChildren().size());
    }

    {
      // Setup a new session. The bug only does not seem to occur if we use the same session.
      CDOSession session = openSession();
      CDOView view = session.openView();
      CDOResource resource = view.getResource(getResourcePath("/test1"));

      NodeA n1 = (NodeA)resource.getContents().get(0);

      // Checks the tree.
      assertEquals(1, n1.getChildren().size());
      NodeA n2 = n1.getChildren().get(0);
      assertEquals(1, n2.getChildren().size());
      NodeA n3 = n2.getChildren().get(0);
      // Oups... Where is n4!?
      assertEquals(1, n3.getChildren().size());
      NodeA n4 = n3.getChildren().get(0);
      assertEquals(0, n4.getChildren().size());
    }
  }

  private void setNames(NodeA... nodes)
  {
    for (NodeA node : nodes)
    {
      String id = CDOUtil.getCDOObject(node).cdoID().toString();
      msg("Node: " + id);
      node.setName(id);
    }
  }

  private void addCommitContextTracer()
  {
    getRepository().addHandler(new WriteAccessHandler()
    {
      public void handleTransactionBeforeCommitting(ITransaction transaction, CommitContext commitContext,
          OMMonitor monitor) throws RuntimeException
      {
        msg(toPrettyString("\t", commitContext.getDirtyObjectDeltas()));
      }

      public void handleTransactionAfterCommitted(ITransaction transaction, CommitContext commitContext,
          OMMonitor monitor)
      {
      }

      /**
       * Prints the {@link InternalCDORevisionDelta}s in a more friendly way than {@link #toString()}.
       *
       * @param spacer
       *          the spacer used to increment the output
       * @return {@link String}
       */
      private String toPrettyString(String spacer, InternalCDORevisionDelta[] dirtyObjects)
      {
        StringBuilder sb = new StringBuilder();

        // Delta.
        sb.append(spacer).append("Delta revision(s):\n");
        for (InternalCDORevisionDelta item : dirtyObjects)
        {
          String m = MessageFormat.format("{0}@{1}:{2}v{3}", item.getEClass().getName(), item.getID(),
              item.getBranch().getID(), item.getVersion());
          sb.append(spacer).append(spacer).append(m).append("\n");
          // Feature deltas.
          for (CDOFeatureDelta delta : item.getFeatureDeltas())
          {
            printFeatureDelta(sb, delta, spacer, 3);
          }
        }

        return sb.toString();
      }

      /**
       * Pretty prints {@link CDOFeatureDelta}, recursing into {@link CDOListFeatureDelta}.
       *
       * @param sb
       *          {@link StringBuilder} where the output is written
       * @param delta
       *          {@link CDOFeatureDelta}
       * @param spacer
       *          the spacer used to increment the output
       * @param numberOfSpacer
       *          the minimal number of spacer in front of a line
       */
      private void printFeatureDelta(StringBuilder sb, CDOFeatureDelta delta, String spacer, int numberOfSpacer)
      {
        if (delta instanceof CDOListFeatureDelta)
        {
          CDOListFeatureDelta list = (CDOListFeatureDelta)delta;
          for (int i = 0; i < numberOfSpacer; i++)
          {
            sb.append(spacer);
          }

          sb.append("CDOListFeatureDelta").append("\n");
          for (CDOFeatureDelta c : list.getListChanges())
          {
            sb.append(spacer);
            printFeatureDelta(sb, c, spacer, numberOfSpacer);
          }
        }
        else
        {
          for (int i = 0; i < numberOfSpacer; i++)
          {
            sb.append(spacer);
          }

          sb.append(delta).append("\n");
        }
      }
    });
  }
}
