/**
 * 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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.hadoop.ozone.om.response.key;

import com.google.common.annotations.VisibleForTesting;
import org.apache.hadoop.ozone.om.OMMetadataManager;
import org.apache.hadoop.ozone.om.helpers.OmKeyInfo;
import org.apache.hadoop.ozone.om.response.OMClientResponse;
import org.apache.hadoop.ozone.protocol.proto.OzoneManagerProtocolProtos
    .OMResponse;
import org.apache.hadoop.hdds.utils.db.BatchOperation;

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

/**
 * Response for RenameKey request.
 */
public class OMKeyRenameResponse extends OMClientResponse {

  private String fromKeyName;
  private String toKeyName;
  private OmKeyInfo newKeyInfo;

  public OMKeyRenameResponse(@Nonnull OMResponse omResponse,
      String fromKeyName, String toKeyName, @Nonnull OmKeyInfo renameKeyInfo) {
    super(omResponse);
    this.fromKeyName = fromKeyName;
    this.toKeyName = toKeyName;
    this.newKeyInfo = renameKeyInfo;
  }

  /**
   * When Rename request is replayed and toKey already exists, but fromKey
   * has not been deleted.
   * For example, lets say we have the following sequence of transactions
   *  Trxn 1 : Create Key1
   *  Trnx 2 : Rename Key1 to Key2 -> Deletes Key1 and Creates Key2
   *  Now if these transactions are replayed:
   *  Replay Trxn 1 : Creates Key1 again as Key1 does not exist in DB
   *  Replay Trxn 2 : Key2 is not created as it exists in DB and the request
   *  would be deemed a replay. But Key1 is still in the DB and needs to be
   *  deleted.
   */
  public OMKeyRenameResponse(@Nonnull OMResponse omResponse,
      String fromKeyName, OmKeyInfo fromKeyInfo) {
    super(omResponse);
    this.fromKeyName = fromKeyName;
    this.newKeyInfo = fromKeyInfo;
    this.toKeyName = null;
  }

  /**
   * For when the request is not successful or it is a replay transaction.
   * For a successful request, the other constructor should be used.
   */
  public OMKeyRenameResponse(@Nonnull OMResponse omResponse) {
    super(omResponse);
    checkStatusNotOK();
  }

  @Override
  public void addToDBBatch(OMMetadataManager omMetadataManager,
      BatchOperation batchOperation) throws IOException {
    String volumeName = newKeyInfo.getVolumeName();
    String bucketName = newKeyInfo.getBucketName();
    // If toKeyName is null, then we need to only delete the fromKeyName from
    // KeyTable. This is the case of replay where toKey exists but fromKey
    // has not been deleted.
    if (deleteFromKeyOnly()) {
      omMetadataManager.getKeyTable().deleteWithBatch(batchOperation,
          omMetadataManager.getOzoneKey(volumeName, bucketName, fromKeyName));
    } else if (createToKeyAndDeleteFromKey()) {
      // At this point we can also update the KeyIdTable.
      if (newKeyInfo.getFileHandleInfo() != 0) {
        omMetadataManager.getKeyIdTable().putWithBatch(batchOperation,
            omMetadataManager.getOzoneKeyIdTableKey(
                newKeyInfo.getFileHandleInfo()), toKeyName);
      }
      // If both from and toKeyName are equal do nothing
      omMetadataManager.getKeyTable().putWithBatch(batchOperation,
          omMetadataManager.getOzoneKey(volumeName, bucketName, toKeyName),
          newKeyInfo);
      omMetadataManager.getKeyTable().deleteWithBatch(batchOperation,
          omMetadataManager.getOzoneKey(volumeName, bucketName, fromKeyName));
    }
  }

  @VisibleForTesting
  public boolean deleteFromKeyOnly() {
    return toKeyName == null && fromKeyName != null;
  }

  @VisibleForTesting
  public boolean createToKeyAndDeleteFromKey() {
    return toKeyName != null && !toKeyName.equals(fromKeyName);
  }
}
