/*
 * Copyright (c) 2011, 2012, 2015, 2016, 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.common.lock;

import org.eclipse.emf.cdo.common.CDOCommonRepository;
import org.eclipse.emf.cdo.common.branch.CDOBranchPoint;
import org.eclipse.emf.cdo.common.id.CDOID;

import org.eclipse.net4j.util.concurrent.IRWLockManager.LockType;

import java.util.Map;

/**
 * Manages all persistent aspects of durable CDO views such as {@link CDOBranchPoint branch point} and acquired locks.
 *
 * @author Eike Stepper
 * @since 4.0
 */
public interface IDurableLockingManager
{
  public LockArea createLockArea(String userID, CDOBranchPoint branchPoint, boolean readOnly, Map<CDOID, LockGrade> locks)
      throws LockAreaAlreadyExistsException;

  /**
   * Returns the {@link LockArea lock area} specified by the given durableLockingID, never <code>null</code>.
   *
   * @throws LockAreaNotFoundException
   *           if the given durableLockingID is unknown.
   */
  public LockArea getLockArea(String durableLockingID) throws LockAreaNotFoundException;

  public void getLockAreas(String userIDPrefix, LockArea.Handler handler);

  public void deleteLockArea(String durableLockingID);

  /**
   * Encapsulates the persistable information about a single durable CDO view like {@link CDOBranchPoint branch point}
   * and acquired locks.
   *
   * @author Eike Stepper
   * @noextend This interface is not intended to be extended by clients.
   * @noimplement This interface is not intended to be implemented by clients.
   */
  public interface LockArea extends CDOBranchPoint
  {
    /**
     * @since 4.1
     */
    public static final int DEFAULT_DURABLE_LOCKING_ID_BYTES = 32;

    public String getDurableLockingID();

    public String getUserID();

    public boolean isReadOnly();

    public Map<CDOID, LockGrade> getLocks();

    /**
     * Returns <code>true</code> if this instance represents a lock area that is known to be missing (not present) on a
     * master server. (Relevant only in a replicating configuration.)
     *
     * @since 4.1
     */
    public boolean isMissing();

    /**
     * A call-back interface for <em>handling</em> {@link LockArea lock area} objects.
     *
     * @author Eike Stepper
     */
    @FunctionalInterface
    public interface Handler
    {
      public boolean handleLockArea(LockArea area);
    }
  }

  /**
   * Thrown if a {@link LockArea lock area} is spcified that does not exist in a CDO {@link CDOCommonRepository
   * repository}.
   *
   * @author Eike Stepper
   */
  public static class LockAreaNotFoundException extends IllegalStateException
  {
    private static final long serialVersionUID = 1L;

    private String durableLockingID;

    public LockAreaNotFoundException(String durableLockingID)
    {
      super("No lock area for ID=" + durableLockingID);
      this.durableLockingID = durableLockingID;
    }

    public LockAreaNotFoundException(String message, Throwable cause, String durableLockingID)
    {
      super(message, cause);
      this.durableLockingID = durableLockingID;
    }

    public String getDurableLockingID()
    {
      return durableLockingID;
    }
  }

  /**
   * Exception occurs when attempting to create a durable {@link LockArea} that already exists.
   *
   * @author Caspar De Groot
   * @since 4.1
   */
  public static class LockAreaAlreadyExistsException extends IllegalStateException
  {
    private static final long serialVersionUID = 1L;

    private String durableLockingID;

    public LockAreaAlreadyExistsException(String durableLockingID)
    {
      super("A lock area with ID=" + durableLockingID + " already exists");
      this.durableLockingID = durableLockingID;
    }

    public String getDurableLockingID()
    {
      return durableLockingID;
    }
  }

  /**
   * Enumerates the possible combinations of read and write locks on a single CDO object.
   *
   * @author Eike Stepper
   * @noextend This interface is not intended to be extended by clients.
   */
  public enum LockGrade
  {
    NONE(0), READ(1), WRITE(2), READ_WRITE(READ.getValue() | WRITE.getValue()),

    /**
     * @since 4.1
     */
    OPTION(4),

    /**
     * @since 4.1
     */
    READ_OPTION(READ.getValue() | OPTION.getValue()),

    /**
     * @since 4.1
     */
    WRITE_OPTION(WRITE.getValue() | OPTION.getValue()),

    /**
     * @since 4.1
     */
    READ_WRITE_OPTION(READ.getValue() | WRITE.getValue() | OPTION.getValue());

    private final int value;

    private LockGrade(int value)
    {
      this.value = value;
    }

    public int getValue()
    {
      return value;
    }

    public boolean isRead()
    {
      return (value & 1) != 0;
    }

    public boolean isWrite()
    {
      return (value & 2) != 0;
    }

    /**
     * @since 4.1
     */
    public boolean isOption()
    {
      return (value & 4) != 0;
    }

    public LockGrade getUpdated(LockType type, boolean on)
    {
      int mask = getMask(type);

      if (on)
      {
        return get(value | mask);
      }

      return get(value & ~mask);
    }

    private int getMask(LockType type)
    {
      switch (type)
      {
      case READ:
        return 1;

      case WRITE:
        return 2;

      case OPTION:
        return 4;
      }

      return 0;
    }

    public static LockGrade get(LockType type)
    {
      if (type == LockType.READ)
      {
        return READ;
      }

      if (type == LockType.WRITE)
      {
        return WRITE;
      }

      if (type == LockType.OPTION)
      {
        return OPTION;
      }

      return NONE;
    }

    /**
     * @deprecated Use {@link #get(boolean, boolean, boolean)}
     */
    @Deprecated
    public static LockGrade get(boolean read, boolean write)
    {
      return get((read ? 1 : 0) | (write ? 2 : 0));
    }

    /**
     * @since 4.1
     */
    public static LockGrade get(boolean read, boolean write, boolean option)
    {
      return get((read ? 1 : 0) | (write ? 2 : 0) | (option ? 4 : 0));
    }

    public static LockGrade get(int value)
    {
      switch (value)
      {
      case 0:
        return NONE;

      case 1:
        return READ;

      case 2:
        return WRITE;

      case 3:
        return READ_WRITE;

      case 4:
        return OPTION;

      case 1 | 4:
        return READ_OPTION;

      case 2 | 4:
        return WRITE_OPTION;

      case 1 | 2 | 4:
        return READ_WRITE_OPTION;

      default:
        throw new IllegalArgumentException("Invalid lock grade: " + value);
      }
    }
  }
}
