/*
 * Copyright (c) 2019 Eike Stepper (Loehne, 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.CDOCommonSession.Options.PassiveUpdateMode;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.protocol.CDOProtocol.CommitNotificationInfo;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.internal.server.SessionManager;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.spi.server.ICommitConflictResolver;
import org.eclipse.emf.cdo.tests.AbstractCDOTest;
import org.eclipse.emf.cdo.tests.config.IRepositoryConfig;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesAfter;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest.CleanRepositoriesBefore;
import org.eclipse.emf.cdo.tests.config.impl.RepositoryConfig;
import org.eclipse.emf.cdo.tests.model1.Company;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUtil;

import org.eclipse.emf.internal.cdo.session.CDOTransactionContainerImpl.TransactionCreator;
import org.eclipse.emf.internal.cdo.transaction.CDOTransactionImpl;

import org.eclipse.net4j.util.io.IOUtil;

import org.eclipse.emf.spi.cdo.InternalCDOTransaction;

import java.util.ArrayList;
import java.util.List;

/**
 * Bug 547640 - Support server-side commit conflict resolution.
 *
 * @author Eike Stepper
 */
@CleanRepositoriesBefore(reason = "server-side merging")
@CleanRepositoriesAfter(reason = "server-side merging")
public class Bugzilla_547640_Test extends AbstractCDOTest
{
  @Requires(IRepositoryConfig.CAPABILITY_AUDITING)
  public void testCommitConflictResolver_OneCommit() throws Exception
  {
    run(new TestLogic()
    {
      private int expectedVersion;

      public void modifyAndCommit1(CDOTransaction transaction, Company company) throws Exception
      {
        company.getCategories().add(getModel1Factory().createCategory());
        transaction.commit();
        expectedVersion = CDOUtil.getCDOObject(company).cdoRevision().getVersion() + 1;
      }

      public void modify2(CDOTransaction transaction, Company company) throws Exception
      {
        company.getCategories().add(getModel1Factory().createCategory());
      }

      public void verify2(CDOTransaction transaction, Company company) throws Exception
      {
        CDORevision cdoRevision = CDOUtil.getCDOObject(company).cdoRevision();
        assertEquals(expectedVersion, cdoRevision.getVersion());

        assertEquals(2, company.getCategories().size());
      }
    });
  }

  @Requires(IRepositoryConfig.CAPABILITY_AUDITING)
  public void testCommitConflictResolver_TwoCommits() throws Exception
  {
    run(new TestLogic()
    {
      private int expectedVersion;

      public void modifyAndCommit1(CDOTransaction transaction, Company company) throws Exception
      {
        company.getCategories().add(getModel1Factory().createCategory());
        transaction.commit();
        company.getCategories().add(getModel1Factory().createCategory());
        transaction.commit();
        expectedVersion = CDOUtil.getCDOObject(company).cdoRevision().getVersion() + 1;
      }

      public void modify2(CDOTransaction transaction, Company company) throws Exception
      {
        company.getCategories().add(getModel1Factory().createCategory());
      }

      public void verify2(CDOTransaction transaction, Company company) throws Exception
      {
        CDORevision cdoRevision = CDOUtil.getCDOObject(company).cdoRevision();
        assertEquals(expectedVersion, cdoRevision.getVersion());
      }
    });
  }

  @Override
  protected void doSetUp() throws Exception
  {
    super.doSetUp();
    getTestProperties().put(RepositoryConfig.PROP_TEST_COMMIT_CONFLICT_RESOLVER, new ICommitConflictResolver.Merging());
    getTestProperties().put(RepositoryConfig.PROP_TEST_SESSION_MANAGER, new SuspendableSessionManager());
  }

  @Override
  protected void doTearDown() throws Exception
  {
    TransactionCreator.reset();
    super.doTearDown();
  }

  protected SuspendableSessionManager getSessionManager()
  {
    return (SuspendableSessionManager)getTestProperties().get(RepositoryConfig.PROP_TEST_SESSION_MANAGER);
  }

  private void run(final TestLogic testLogic) throws Exception
  {
    CDOSession session1 = openSession();
    CDOTransaction transaction1 = session1.openTransaction();
    Company company1 = getModel1Factory().createCompany();
    transaction1.createResource(getResourcePath("resource")).getContents().add(company1);
    transaction1.commit();

    CDOSession session2 = openSession();
    session2.options().setPassiveUpdateMode(PassiveUpdateMode.CHANGES);
    TransactionCreator.set(new TransactionCreator()
    {
      @Override
      public InternalCDOTransaction createTransaction(CDOSession session, CDOBranch branch)
      {
        return new CDOTransactionImpl(session, branch)
        {
          @Override
          protected void waitForBaseline(long previousTimeStamp)
          {
            getSessionManager().resume();
            super.waitForBaseline(previousTimeStamp);
          }
        };
      }
    });

    final CDOTransaction transaction2 = session2.openTransaction();
    TransactionCreator.reset();

    final Company company2 = (Company)transaction2.getResource(getResourcePath("resource")).getContents().get(0);

    // Let client2 modify the model (but not commit, yet).
    testLogic.modify2(transaction2, company2);

    // Let client1 modify the model and commit (but hold back commit notifications to client2).
    getSessionManager().suspend();
    testLogic.modifyAndCommit1(transaction1, company1);

    // Let client2 commit and verify the result.
    transaction2.commit();
    testLogic.verify2(transaction2, company2);
  }

  /**
   * @author Eike Stepper
   */
  private static class SuspendableSessionManager extends SessionManager
  {
    private List<CommitNotificationInfo> queue;

    public synchronized void suspend()
    {
      IOUtil.OUT().println("Suspending commit notifications");
      queue = new ArrayList<CommitNotificationInfo>();
    }

    public synchronized void resume()
    {
      IOUtil.OUT().println("Resuming commit notifications");

      try
      {
        for (CommitNotificationInfo info : queue)
        {
          super.sendCommitNotification(info);
        }
      }
      finally
      {
        queue = null;
      }
    }

    @Override
    public synchronized void sendCommitNotification(CommitNotificationInfo info)
    {
      if (queue != null)
      {
        queue.add(info);
      }
      else
      {
        super.sendCommitNotification(info);
      }
    }
  }

  /**
   * @author Eike Stepper
   */
  public interface TestLogic
  {
    public void modifyAndCommit1(CDOTransaction transaction, Company company) throws Exception;

    public void modify2(CDOTransaction transaction, Company company) throws Exception;

    public void verify2(CDOTransaction transaction, Company company) throws Exception;
  }
}
