/*
 * 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.hbase.txprune;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest;
import org.apache.tephra.Transaction;
import org.apache.tephra.persist.TransactionVisibilityState;
import org.apache.tephra.util.TxUtils;

import java.io.IOException;
import javax.annotation.Nullable;

/**
 * Record compaction state for invalid list pruning
 */
public class CompactionState {
  private static final Log LOG = LogFactory.getLog(CompactionState.class);

  private final byte[] regionName;
  private final String regionNameAsString;
  private final PruneUpperBoundWriterSupplier pruneUpperBoundWriterSupplier;
  private final PruneUpperBoundWriter pruneUpperBoundWriter;

  private volatile long pruneUpperBound = -1;

  public CompactionState(final RegionCoprocessorEnvironment env, final TableName stateTable, long pruneFlushInterval) {
    this.regionName = env.getRegionInfo().getRegionName();
    this.regionNameAsString = env.getRegionInfo().getRegionNameAsString();
    DataJanitorState dataJanitorState = new DataJanitorState(new DataJanitorState.TableSupplier() {
      @Override
      public Table get() throws IOException {
        return env.getConnection().getTable(stateTable);
      }
    });
    this.pruneUpperBoundWriterSupplier = new PruneUpperBoundWriterSupplier(stateTable, dataJanitorState,
                                                                           pruneFlushInterval);
    this.pruneUpperBoundWriter = pruneUpperBoundWriterSupplier.get();
  }

  /**
   * Records the transaction state used for a compaction. This method is called when the compaction starts.
   *
   * @param request {@link CompactionRequest} for the compaction
   * @param snapshot transaction state that will be used for the compaction
   */
  public void record(CompactionRequest request, @Nullable TransactionVisibilityState snapshot) {
    if (request.isMajor() && snapshot != null) {
      Transaction tx = TxUtils.createDummyTransaction(snapshot);
      pruneUpperBound = TxUtils.getPruneUpperBound(tx);
      if (LOG.isDebugEnabled()) {
        LOG.debug(
          String.format("Computed prune upper bound %s for compaction request %s using transaction state from time %s",
                        pruneUpperBound, request, snapshot.getTimestamp()));
      }
    } else {
      pruneUpperBound = -1;
    }
  }

  /**
   * Persists the transaction state recorded by {@link #record(CompactionRequest, TransactionVisibilityState)}.
   * This method is called after the compaction has successfully completed.
   */
  public void persist() {
    if (pruneUpperBound != -1) {
      pruneUpperBoundWriter.persistPruneEntry(regionName, pruneUpperBound);
      if (LOG.isDebugEnabled()) {
        LOG.debug(String.format("Enqueued prune upper bound %s for region %s", pruneUpperBound, regionNameAsString));
      }
    }
  }

  /**
   * Persist that the given region is empty at the given time
   * @param time time in milliseconds
   */
  public void persistRegionEmpty(long time) {
    pruneUpperBoundWriter.persistRegionEmpty(regionName, time);
    if (LOG.isDebugEnabled()) {
      LOG.debug(String.format("Enqueued empty region %s at time %s", regionNameAsString, time));
    }
  }

  /**
   * Releases the usage {@link PruneUpperBoundWriter}.
   */
  public void stop() {
    pruneUpperBoundWriterSupplier.release();
  }
}
