/*
 * Copyright (c) 2011, 2012, 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.CDOLock;
import org.eclipse.emf.cdo.CDOObject;
import org.eclipse.emf.cdo.common.lock.CDOLockChangeInfo;
import org.eclipse.emf.cdo.internal.net4j.CDONet4jSessionConfigurationImpl;
import org.eclipse.emf.cdo.internal.net4j.CDONet4jSessionImpl;
import org.eclipse.emf.cdo.net4j.CDONet4jSessionConfiguration;
import org.eclipse.emf.cdo.util.CDOUtil;

import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.spi.cdo.InternalCDOSession;
import org.eclipse.emf.spi.cdo.InternalCDOView;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author Eike Stepper
 */
public class AbstractLockingTest extends AbstractCDOTest
{
  public static final long NO_DELAY = -1L;

  private final AtomicInteger activeLockNotifications = new AtomicInteger();

  public AbstractLockingTest()
  {
  }

  protected long getInvalidationDelay()
  {
    return NO_DELAY;
  }

  @Override
  protected CDONet4jSessionConfiguration createNet4jSessionConfiguration(String repositoryName)
  {
    return new LockingSessionConfiguration();
  }

  protected final void waitForActiveLockNotifications() throws InterruptedException
  {
    long end = System.currentTimeMillis() + DEFAULT_TIMEOUT;

    while (System.currentTimeMillis() < end)
    {
      synchronized (activeLockNotifications)
      {
        if (activeLockNotifications.get() == 0)
        {
          return;
        }

        activeLockNotifications.wait(100L);
      }
    }
  }

  protected static CDOLock readLock(EObject object) throws InterruptedException
  {
    CDOObject cdoObject = CDOUtil.getCDOObject(object);
    CDOLock lock = cdoObject.cdoReadLock();
    assertEquals(true, lock.tryLock(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS));
    return lock;
  }

  protected static CDOLock readUnlock(EObject object) throws InterruptedException
  {
    CDOObject cdoObject = CDOUtil.getCDOObject(object);
    CDOLock lock = cdoObject.cdoReadLock();
    lock.unlock();
    return lock;
  }

  protected static CDOLock writeLock(EObject object) throws InterruptedException
  {
    CDOObject cdoObject = CDOUtil.getCDOObject(object);
    CDOLock lock = cdoObject.cdoWriteLock();
    assertEquals(true, lock.tryLock(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS));
    return lock;
  }

  protected static CDOLock writeUnlock(EObject object) throws InterruptedException
  {
    CDOObject cdoObject = CDOUtil.getCDOObject(object);
    CDOLock lock = cdoObject.cdoWriteLock();
    lock.unlock();
    return lock;
  }

  protected static CDOLock optionLock(EObject object) throws InterruptedException
  {
    CDOObject cdoObject = CDOUtil.getCDOObject(object);
    CDOLock lock = cdoObject.cdoWriteOption();
    assertEquals(true, lock.tryLock(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS));
    return lock;
  }

  protected static CDOLock optionUnlock(EObject object) throws InterruptedException
  {
    CDOObject cdoObject = CDOUtil.getCDOObject(object);
    CDOLock lock = cdoObject.cdoWriteOption();
    lock.unlock();
    return lock;
  }

  protected static CDOLock assertReadLock(boolean expected, EObject object)
  {
    CDOObject cdoObject = CDOUtil.getCDOObject(object);
    CDOLock lock = cdoObject.cdoReadLock();
    assertEquals(expected, lock.isLocked());
    return lock;
  }

  protected static CDOLock assertWriteLock(boolean expected, EObject object)
  {
    CDOObject cdoObject = CDOUtil.getCDOObject(object);
    CDOLock lock = cdoObject.cdoWriteLock();
    assertEquals(expected, lock.isLocked());
    return lock;
  }

  protected static void assertOptionLock(boolean expected, EObject object)
  {
    CDOObject cdoObject = CDOUtil.getCDOObject(object);
    CDOLock lock = cdoObject.cdoWriteOption();
    assertEquals(expected, lock.isLocked());
  }

  /**
   * @author Eike Stepper
   */
  protected class LockingSessionConfiguration extends CDONet4jSessionConfigurationImpl
  {
    @Override
    public InternalCDOSession createSession()
    {
      return new CDONet4jSessionImpl()
      {
        @Override
        public void handleLockNotification(CDOLockChangeInfo lockChangeInfo, InternalCDOView sender, boolean async)
        {
          synchronized (activeLockNotifications)
          {
            activeLockNotifications.incrementAndGet();
            activeLockNotifications.notifyAll();
          }

          super.handleLockNotification(lockChangeInfo, sender, async);
        }

        @Override
        protected void doHandleLockNotification(CDOLockChangeInfo lockChangeInfo, InternalCDOView sender)
        {
          super.doHandleLockNotification(lockChangeInfo, sender);

          synchronized (activeLockNotifications)
          {
            activeLockNotifications.decrementAndGet();
            activeLockNotifications.notifyAll();
          }
        }

        @Override
        public void invalidate(InvalidationData invalidationData)
        {
          long delay = getInvalidationDelay();
          if (delay != NO_DELAY)
          {
            sleep(delay); // Delay the invalidation handling to give lock notifications a chance to overtake.
          }

          super.invalidate(invalidationData);
        }

      };
    }
  }
}
