/*
 * Copyright (c) 2007-2013, 2016, 2019, 2020 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;

import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.CDOState;
import org.eclipse.emf.cdo.common.branch.CDOBranch;
import org.eclipse.emf.cdo.common.commit.CDOCommitInfo;
import org.eclipse.emf.cdo.common.id.CDOID;
import org.eclipse.emf.cdo.common.id.CDOIDUtil;
import org.eclipse.emf.cdo.common.lock.CDOLockState;
import org.eclipse.emf.cdo.common.model.CDOPackageTypeRegistry;
import org.eclipse.emf.cdo.common.revision.CDOAllRevisionsProvider;
import org.eclipse.emf.cdo.common.revision.CDOIDAndBranch;
import org.eclipse.emf.cdo.common.revision.CDORevision;
import org.eclipse.emf.cdo.common.revision.CDORevisionUtil;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.cdo.net4j.CDONet4jUtil;
import org.eclipse.emf.cdo.server.IView;
import org.eclipse.emf.cdo.session.CDORepositoryInfo;
import org.eclipse.emf.cdo.session.CDOSession;
import org.eclipse.emf.cdo.spi.server.InternalLockManager;
import org.eclipse.emf.cdo.spi.server.InternalRepository;
import org.eclipse.emf.cdo.spi.server.InternalSession;
import org.eclipse.emf.cdo.spi.server.InternalTransaction;
import org.eclipse.emf.cdo.spi.server.InternalView;
import org.eclipse.emf.cdo.tests.config.impl.ConfigTest;
import org.eclipse.emf.cdo.transaction.CDOTransaction;
import org.eclipse.emf.cdo.util.CDOUpdatable;
import org.eclipse.emf.cdo.util.CDOUtil;
import org.eclipse.emf.cdo.util.CommitException;
import org.eclipse.emf.cdo.view.CDOView;

import org.eclipse.emf.internal.cdo.object.CDOLegacyWrapper;

import org.eclipse.net4j.util.ReflectUtil;
import org.eclipse.net4j.util.StringUtil;
import org.eclipse.net4j.util.concurrent.RWOLockManager.LockState;
import org.eclipse.net4j.util.concurrent.TimeoutRuntimeException;
import org.eclipse.net4j.util.event.IEvent;
import org.eclipse.net4j.util.event.IListener;
import org.eclipse.net4j.util.event.ThrowableEvent;
import org.eclipse.net4j.util.io.IOUtil;
import org.eclipse.net4j.util.tests.AbstractOMTest;

import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EReference;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceFactoryRegistryImpl;
import org.eclipse.emf.spi.cdo.FSMUtil;

import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @author Eike Stepper
 */
public abstract class AbstractCDOTest extends ConfigTest
{
  static
  {
    // Make sure that the Net4j resource factories are registered before registrations become impossible.
    CDONet4jUtil.createNet4jSessionConfiguration();

    makeUnmodifiable("protocolToFactoryMap");
    makeUnmodifiable("extensionToFactoryMap");
    makeUnmodifiable("contentTypeIdentifierToFactoryMap");
  }

  private static void makeUnmodifiable(String fieldName)
  {
    Field field = ReflectUtil.getField(ResourceFactoryRegistryImpl.class, fieldName);

    @SuppressWarnings("unchecked")
    Map<String, Object> map = (Map<String, Object>)ReflectUtil.getValue(field, Resource.Factory.Registry.INSTANCE);
    ReflectUtil.setValue(field, Resource.Factory.Registry.INSTANCE, Collections.unmodifiableMap(map));
  }

  @Override
  protected void doSetUp() throws Exception
  {
    try
    {
      super.doSetUp();
    }
    finally
    {
      org.eclipse.emf.cdo.internal.net4j.bundle.OM.PREF_COMMIT_MONITOR_PROGRESS_SECONDS.setValue(60);
      org.eclipse.emf.cdo.internal.net4j.bundle.OM.PREF_COMMIT_MONITOR_TIMEOUT_SECONDS.setValue(60 * 60);
      CDOPackageTypeRegistry.INSTANCE.reset();
      startTransport();
    }
  }

  @Override
  protected void doTearDown() throws Exception
  {
    // This override adds no functionality.
    // It just ensures that the IDE shows doSetUp() and doTearDown() in the same class.
    super.doTearDown();
  }

  /**
   * Closes the given session and waits until the server-side session is closed, too.
   * In TCP scenarios the latter does not happen synchronously, which can confuse tests that count sessions.
   */
  public void closeSession(CDOSession session) throws InterruptedException
  {
    final int sessionID = session.getSessionID();
    session.close();

    new PollingTimeOuter()
    {
      @Override
      protected boolean successful()
      {
        return getRepository().getSessionManager().getSession(sessionID) == null;
      }
    }.assertNoTimeOut();
  }

  public InternalSession serverSession(CDOSession session)
  {
    String repositoryName = session.getRepositoryInfo().getName();
    InternalRepository repository = getRepository(repositoryName);
    return repository.getSessionManager().getSession(session.getSessionID());
  }

  public InternalView serverView(CDOView view)
  {
    InternalSession serverSession = serverSession(view.getSession());
    return serverSession.getView(view.getViewID());
  }

  public InternalTransaction serverTransaction(CDOTransaction transaction)
  {
    return (InternalTransaction)serverView(transaction);
  }

  public CDOBranch serverBranch(CDOBranch branch)
  {
    CDORepositoryInfo repositoryInfo = (CDORepositoryInfo)branch.getBranchManager().getRepository();
    InternalRepository repository = getRepository(repositoryInfo.getName());
    return repository.getBranchManager().getBranch(branch.getID());
  }

  public LockState<Object, IView> serverLockState(CDOSession session, CDOLockState lockState)
  {
    Object serverLockTarget = serverLockTarget(lockState.getLockedObject());

    InternalSession serverSession = serverSession(session);
    InternalLockManager lockingManager = serverSession.getManager().getRepository().getLockingManager();
    return lockingManager.getLockState(serverLockTarget);
  }

  public Object serverLockTarget(Object lockTarget)
  {
    if (lockTarget instanceof CDOIDAndBranch)
    {
      CDOIDAndBranch idAndBranch = (CDOIDAndBranch)lockTarget;
      CDOBranch serverBranch = serverBranch(idAndBranch.getBranch());
      return CDOIDUtil.createIDAndBranch(idAndBranch.getID(), serverBranch);
    }

    return lockTarget;
  }

  public static void assertEquals(Object expected, Object actual)
  {
    if (expected instanceof CDOID || expected instanceof CDOBranch)
    {
      if (expected != actual)
      {
        failNotEquals(null, expected, actual);
      }

      return;
    }

    // IMPORTANT: Give possible CDOLegacyWrapper a chance for actual, too
    if (actual != null && actual.equals(expected))
    {
      return;
    }

    AbstractOMTest.assertEquals(expected, actual);
  }

  protected static void assertTransient(EObject eObject)
  {
    CDOObject object = CDOUtil.getCDOObject(eObject);
    if (object != null)
    {
      assertEquals(true, FSMUtil.isTransient(object));
      assertNull(object.cdoID());
      assertNull(object.cdoRevision());
      assertNull(object.cdoView());
    }
  }

  protected static void assertInvalid(EObject eObject)
  {
    CDOObject object = CDOUtil.getCDOObject(eObject);
    if (object != null)
    {
      assertEquals(true, FSMUtil.isInvalid(object));
    }
  }

  protected static void assertNotTransient(EObject eObject, CDOView view)
  {
    CDOObject object = FSMUtil.adapt(eObject, view);
    assertEquals(false, FSMUtil.isTransient(object));
    assertNotNull(object.cdoID());
    assertNotNull(object.cdoRevision());
    assertNotNull(object.cdoView());
    assertNotNull(object.eResource());
    assertEquals(view, object.cdoView());
    assertEquals(object, view.getObject(object.cdoID(), false));
  }

  protected static void assertNew(EObject eObject, CDOView view)
  {
    CDOObject object = FSMUtil.adapt(eObject, view);
    assertNotTransient(object, view);
    assertEquals(CDOState.NEW, object.cdoState());
  }

  protected static void assertDirty(EObject eObject, CDOView view)
  {
    CDOObject object = FSMUtil.adapt(eObject, view);
    assertNotTransient(object, view);
    assertEquals(CDOState.DIRTY, object.cdoState());
  }

  protected static void assertClean(EObject eObject, CDOView view)
  {
    CDOObject object = FSMUtil.adapt(eObject, view);
    assertNotTransient(object, view);
    assertEquals(CDOState.CLEAN, object.cdoState());
  }

  protected static void assertProxy(EObject eObject)
  {
    CDOObject object = CDOUtil.getCDOObject(eObject);
    if (object != null)
    {
      assertEquals(false, FSMUtil.isTransient(object));
      assertNotNull(object.cdoID());
      assertNotNull(object.cdoView());
      assertEquals(CDOState.PROXY, object.cdoState());
    }
  }

  protected static void assertContent(EObject eContainer, EObject eContained)
  {
    CDOObject container = CDOUtil.getCDOObject(eContainer);
    CDOObject contained = CDOUtil.getCDOObject(eContained);
    if (container != null && contained != null)
    {
      assertEquals(true, container.eContents().contains(contained));
      if (container instanceof CDOResource)
      {
        assertEquals(container, contained.eResource());
        assertEquals(null, contained.eContainer());
        assertEquals(true, ((CDOResource)container).getContents().contains(contained));
      }
      else
      {
        assertEquals(container.eResource(), contained.eResource());
        assertEquals(container, contained.eContainer());
      }
    }
  }

  protected static void assertNotProxy(Object object)
  {
    assertEquals(false, CDOLegacyWrapper.isLegacyProxy(object));
  }

  protected static void assertCreatedTime(EObject eObject, long timeStamp)
  {
    CDOObject object = CDOUtil.getCDOObject(eObject);
    if (object != null)
    {
      assertEquals(timeStamp, object.cdoRevision().getTimeStamp());
    }
  }

  protected static void dumpAllRevisions(Object allRevisionsProvider)
  {
    try
    {
      String label = allRevisionsProvider.toString();
      IOUtil.OUT().println(label);
      for (int i = 0; i < label.length(); i++)
      {
        IOUtil.OUT().print("=");
      }

      IOUtil.OUT().println();
      if (allRevisionsProvider instanceof CDOAllRevisionsProvider)
      {
        CDOAllRevisionsProvider provider = (CDOAllRevisionsProvider)allRevisionsProvider;
        Map<CDOBranch, List<CDORevision>> map = provider.getAllRevisions();
        IOUtil.OUT().println(CDORevisionUtil.dumpAllRevisions(map));
      }
    }
    catch (Exception ex)
    {
      IOUtil.print(ex);
    }
  }

  protected static void dumpAllContents(Notifier root)
  {
    try
    {
      StringBuilder builder = new StringBuilder();
      dumpAllContents(root, "", builder);
      IOUtil.OUT().println(builder);
    }
    catch (Exception ex)
    {
      IOUtil.print(ex);
    }
  }

  private static void dumpAllContents(Notifier object, String indent, StringBuilder builder)
  {
    builder.append(indent);
    if (object instanceof ResourceSet)
    {
      ResourceSet resourceSet = (ResourceSet)object;
      builder.append("ResourceSet");
      builder.append(StringUtil.NL);

      for (Resource resource : resourceSet.getResources())
      {
        dumpAllContents(resource, indent + "  ", builder);
      }
    }
    else if (object instanceof Resource)
    {
      Resource resource = (Resource)object;
      if (object instanceof CDOResource)
      {
        builder.append("CDOResource[uri=" + ((CDOResource)resource).getName() + "]");
      }
      else
      {
        builder.append("Resource[uri=" + resource.getURI() + "]");
      }

      builder.append(StringUtil.NL);
      for (EObject child : resource.getContents())
      {
        dumpAllContents(child, indent + "  ", builder);
      }
    }
    else
    {
      EObject eObject = (EObject)object;
      CDOObject cdoObject = CDOUtil.getCDOObject(eObject);
      builder.append(cdoObject.toString());

      boolean added = false;
      for (EStructuralFeature feature : cdoObject.eClass().getEAllStructuralFeatures())
      {
        if (feature instanceof EReference)
        {
          EReference reference = (EReference)feature;
          if (reference.isContainment() || reference.isContainer())
          {
            continue;
          }
        }

        if (cdoObject.eIsSet(feature))
        {
          if (added)
          {
            builder.append(", ");
          }
          else
          {
            builder.append("[");
          }

          added = true;

          Object value = cdoObject.eGet(feature);
          builder.append(feature.getName() + "=" + value);
        }
      }

      if (added)
      {
        builder.append("]");
      }

      builder.append(StringUtil.NL);
      for (TreeIterator<EObject> it = cdoObject.eAllContents(); it.hasNext();)
      {
        EObject child = it.next();
        dumpAllContents(child, indent + "  ", builder);
      }
    }
  }

  protected static CDOCommitInfo commitAndSync(CDOTransaction transaction, CDOUpdatable... updatables) throws CommitException
  {
    return commitAndSync(transaction, null, updatables);
  }

  protected static CDOCommitInfo commitAndSync(CDOTransaction transaction, String comment, CDOUpdatable... updatables) throws CommitException
  {
    final RuntimeException[] exception = { null };
    IListener listener = new IListener()
    {
      @Override
      public void notifyEvent(IEvent event)
      {
        if (exception[0] == null && event instanceof ThrowableEvent)
        {
          ThrowableEvent e = (ThrowableEvent)event;
          exception[0] = new RuntimeException(e.getThrowable());
        }
      }
    };

    for (CDOUpdatable updatable : updatables)
    {
      if (updatable instanceof CDOView)
      {
        CDOView view = (CDOView)updatable;
        view.addListener(listener);
      }
    }

    try
    {
      if (comment != null)
      {
        transaction.setCommitComment(comment);
      }

      CDOCommitInfo info = transaction.commit();
      if (info != null)
      {
        for (CDOUpdatable updatable : updatables)
        {
          if (!updatable.waitForUpdate(info.getTimeStamp(), DEFAULT_TIMEOUT))
          {
            if (exception[0] == null)
            {
              exception[0] = new TimeoutRuntimeException(updatable.toString() + " did not receive an update of " + info);
            }

            break;
          }
        }
      }

      if (exception[0] != null)
      {
        throw exception[0];
      }

      return info;
    }
    finally
    {
      for (CDOUpdatable updatable : updatables)
      {
        if (updatable instanceof CDOView)
        {
          CDOView view = (CDOView)updatable;
          view.removeListener(listener);
        }
      }
    }
  }
}
