/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.tephra;

import java.util.Arrays;

/**
 * Transaction details
 */
// NOTE: this class should have minimal dependencies as it is used in HBase CPs and other places where minimal classes
//       are available
public class Transaction {
  private final long readPointer;
  private final long txId;
  private final long writePointer;
  private final long[] invalids;
  private final long[] inProgress;
  private final long firstShortInProgress;
  private final TransactionType type;
  private final long[] checkpointWritePointers;

  private VisibilityLevel visibilityLevel = VisibilityLevel.SNAPSHOT;

  private static final long[] NO_EXCLUDES = { };
  public static final long NO_TX_IN_PROGRESS = Long.MAX_VALUE;

  public static final Transaction ALL_VISIBLE_LATEST =
    new Transaction(Long.MAX_VALUE, Long.MAX_VALUE, NO_EXCLUDES, NO_EXCLUDES, NO_TX_IN_PROGRESS, TransactionType.SHORT);

  /**
   * Defines the possible visibility levels for read operations.
   *
   * <p>
   * <ul>
   *   <li><code>SNAPSHOT</code> - uses the transaction's read snapshot, plus includes all write pointers from the
   *       current transaction</li>
   *   <li><code>SNAPSHOT_EXCLUDE_CURRENT</code> - uses the transaction's read snapshot, plus includes all write
   *       pointers from the current transaction, <strong>except</strong> the current write pointer
   *       (see {@link #getWritePointer()})</li>
   *   <li><code>SNAPSHOT_ALL</code> - uses the transaction's read snapshot, plus includes all write pointers from the
   *       current transaction. This visibility level will lead to raw fetch operations, where all versions
   *       (including deletes) visible to current transaction are returned.</li>
   * </ul>
   * </p>
   *
   * <p>The default value used is {@code SNAPSHOT}.</p>
   *
   * @see #setVisibility(VisibilityLevel)
   */
  public enum VisibilityLevel {
    SNAPSHOT,
    SNAPSHOT_EXCLUDE_CURRENT,
    SNAPSHOT_ALL
  }

  /**
   * Creates a new short transaction.
   * @param readPointer read pointer for transaction
   * @param txId unique identifier for the transaction
   * @param invalids list of invalid transactions to exclude while reading
   * @param inProgress list of in-progress transactions to exclude while reading
   * @param firstShortInProgress earliest in-progress short transaction
   */
  public Transaction(long readPointer, long txId, long[] invalids, long[] inProgress,
                     long firstShortInProgress) {
    this(readPointer, txId, invalids, inProgress, firstShortInProgress, TransactionType.SHORT);
  }

  /**
   * Creates a new transaction.
   * @param readPointer read pointer for transaction
   * @param txId unique identifier for the transaction
   * @param invalids list of invalid transactions to exclude while reading
   * @param inProgress list of in-progress transactions to exclude while reading
   * @param firstShortInProgress earliest in-progress short transaction
   * @param type transaction type
   */
  public Transaction(long readPointer, long txId, long[] invalids, long[] inProgress,
                     long firstShortInProgress, TransactionType type) {
    this(readPointer, txId, txId, invalids, inProgress, firstShortInProgress, type, new long[0],
        VisibilityLevel.SNAPSHOT);
  }

  /**
   * Creates a new transaction.
   * @param readPointer read pointer for transaction
   * @param txId unique identifier for the transaction
   * @param writePointer the current pointer to be used for any writes.
   *                      For new transactions, this will be the same as {@code txId}.  For checkpointed
   *                      transactions, this will be the most recent write pointer issued.
   * @param invalids list of invalid transactions to exclude while reading
   * @param inProgress list of in-progress transactions to exclude while reading
   * @param firstShortInProgress earliest in-progress short transaction
   * @param type transaction type
   * @param checkpointPointers the list of writer pointers added from checkpoints on the transaction
   * @param visibilityLevel the visibility level to use for transactional reads
   */
  public Transaction(long readPointer, long txId, long writePointer, long[] invalids, long[] inProgress,
                     long firstShortInProgress, TransactionType type, long[] checkpointPointers,
                     VisibilityLevel visibilityLevel) {
    this.readPointer = readPointer;
    this.txId = txId;
    this.writePointer = writePointer;
    this.invalids = invalids;
    this.inProgress = inProgress;
    this.firstShortInProgress = firstShortInProgress;
    this.type = type;
    this.checkpointWritePointers = checkpointPointers;
    this.visibilityLevel = visibilityLevel;
  }

  /**
   * Creates a new transaction for a checkpoint operation, copying all members from the original transaction,
   * with the updated checkpoint write pointers.
   *
   * @param toCopy the original transaction containing the state to copy
   * @param writePointer the new write pointer to use for the transaction
   * @param checkpointPointers the list of write pointers added from checkpoints on the transaction
   */
  public Transaction(Transaction toCopy, long writePointer, long[] checkpointPointers) {
    this(toCopy.getReadPointer(), toCopy.getTransactionId(), writePointer, toCopy.getInvalids(),
        toCopy.getInProgress(), toCopy.getFirstShortInProgress(), toCopy.getType(), checkpointPointers,
        toCopy.getVisibilityLevel());
  }

  public long getReadPointer() {
    return readPointer;
  }

  /**
   * Returns the initial write pointer assigned to the transaction.  This will remain the same for the life of the
   * transaction, and uniquely identifies it with the transaction service.  This value should be provided
   * to identify the transaction when calling any transaction lifecycle methods on the transaction service.
   */
  public long getTransactionId() {
    return txId;
  }

  /**
   * Returns the write pointer to be used in persisting any changes.  After a checkpoint is performed, this will differ
   * from {@link #getTransactionId()}.  This method should always be used when setting the timestamp for writes
   * in order to ensure that the correct value is used.
   */
  public long getWritePointer() {
    return writePointer;
  }

  public long[] getInvalids() {
    return invalids;
  }

  public long[] getInProgress() {
    return inProgress;
  }

  public long getFirstInProgress() {
    return inProgress.length == 0 ? NO_TX_IN_PROGRESS : inProgress[0];
  }

  public TransactionType getType() {
    return type;
  }

  /**
   * @return transaction id {@code X} such that any of the transactions newer than {@code X} may be invisible to this<p>
   *         NOTE: the returned tx id can be invalid.
   */
  public long getVisibilityUpperBound() {
    // NOTE: in some cases when we do not provide visibility guarantee, we set readPointer to MAX value, but
    //       at same time we don't want that to case cleanup everything as this is used for tx janitor + ttl to see
    //       what can be cleaned up. When non-tx mode is implemented better, we should not need this check
    return inProgress.length == 0 ? Math.min(txId - 1, readPointer) : inProgress[0] - 1;
  }

  public long getFirstShortInProgress() {
    return firstShortInProgress;
  }

  /**
   * Returns true if the given version corresponds to a transaction that was in-progress at the time this transaction
   * started.
   */
  public boolean isInProgress(long version) {
    return Arrays.binarySearch(inProgress, version) >= 0;
  }

  /**
   * Returns true if the given version is present in one of the arrays of excluded versions (in-progress and
   * invalid transactions).
   */
  public boolean isExcluded(long version) {
    return Arrays.binarySearch(inProgress, version) >= 0
      || Arrays.binarySearch(invalids, version) >= 0;
  }

  /**
   * Returns true if the the given version corresponds to one of the checkpoint versions in the current
   * transaction.
   */
  public boolean isCheckpoint(long version) {
    return Arrays.binarySearch(checkpointWritePointers, version) >= 0;
  }

  /**
   * Returns whether or not the given version should be visible to the current transaction.  A version will be visible
   * if it was successfully committed prior to the current transaction starting, or was written by the current
   * transaction (using either the current write pointer or the write pointer from a prior checkpoint).
   *
   * @param version the data version to check for visibility
   * @return true if the version is visible, false if it should be hidden (filtered)
   *
   * @see #setVisibility(VisibilityLevel) to control whether the current write pointer is visible.
   */
  public boolean isVisible(long version) {
    // either it was committed before or the change belongs to current tx
    return (version <= getReadPointer() && !isExcluded(version)) ||
        (isCurrentWrite(version) &&
            (visibilityLevel != VisibilityLevel.SNAPSHOT_EXCLUDE_CURRENT || writePointer != version));
  }

  /**
   * Returns whether the given version was written by the current transaction.
   *
   * @param version the data version
   * @return true if version was written by current transaction, false otherwise.
   */
  public boolean isCurrentWrite(long version) {
    return writePointer == version || txId == version || isCheckpoint(version);
  }

  /**
   * Sets the visibility level for read operations.
   */
  public void setVisibility(VisibilityLevel level) {
    this.visibilityLevel = level;
  }

  /**
   * Returns the currently set visibility level.
   */
  public VisibilityLevel getVisibilityLevel() {
    return visibilityLevel;
  }

  public boolean hasExcludes() {
    return invalids.length > 0 || inProgress.length > 0;
  }


  public int excludesSize() {
    return invalids.length + inProgress.length;
  }

  /**
   * Returns any prior write pointers used in the current transaction.  A new write pointer is issued when the
   * {@code TransactionContext.checkpoint(Transaction)} operation is called, and the prior write pointer is added
   * to the array of checkpoint write pointers.
`   */
  public long[] getCheckpointWritePointers() {
    return checkpointWritePointers;
  }

  @Override
  public String toString() {
    return new StringBuilder(100)
      .append(Transaction.class.getSimpleName())
      .append('{')
      .append("readPointer: ").append(readPointer)
      .append(", transactionId: ").append(txId)
      .append(", writePointer: ").append(writePointer)
      .append(", invalids: ").append(Arrays.toString(invalids))
      .append(", inProgress: ").append(Arrays.toString(inProgress))
      .append(", firstShortInProgress: ").append(firstShortInProgress)
      .append(", type: ").append(type)
      .append(", checkpointWritePointers: ").append(Arrays.toString(checkpointWritePointers))
      .append(", visibilityLevel: ").append(visibilityLevel)
      .append('}')
      .toString();
  }
}
