/*
 * 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.hadoop.fs.s3a.performance;

/**
 * Declaration of the costs of head and list calls for various FS IO
 * operations.
 * <p></p>
 * An instance declares the number of head and list calls expected for
 * various operations -with a {@link #plus(OperationCost)}
 * method to add operation costs together to produce an
 * aggregate cost. These can then be validated in tests
 * via {@link OperationCostValidator}.
 *
 */
public final class OperationCost {

  /** Head costs for getFileStatus() directory probe: {@value}. */
  public static final int FILESTATUS_DIR_PROBE_H = 0;

  /** List costs for getFileStatus() directory probe: {@value}. */
  public static final int FILESTATUS_DIR_PROBE_L = 1;

  /** Head cost getFileStatus() file probe only. */
  public static final int FILESTATUS_FILE_PROBE_H = 1;

  /** Liast cost getFileStatus() file probe only. */

  public static final int FILESTATUS_FILE_PROBE_L = 0;

  /**
   * Delete cost when deleting an object.
   */
  public static final int DELETE_OBJECT_REQUEST = 1;

  /**
   * Delete cost when deleting a marker.
   */
  public static final int DELETE_MARKER_REQUEST = DELETE_OBJECT_REQUEST;

  /**
   * No IO takes place.
   */
  public static final OperationCost NO_IO =
      new OperationCost(0, 0);

  /** A HEAD operation. */
  public static final OperationCost HEAD_OPERATION = new OperationCost(1, 0);

  /** A LIST operation. */
  public static final OperationCost LIST_OPERATION = new OperationCost(0, 1);

  /**
   * Cost of {@link org.apache.hadoop.fs.s3a.impl.StatusProbeEnum#DIRECTORIES}.
   */
  public static final OperationCost FILE_STATUS_DIR_PROBE = LIST_OPERATION;

  /**
   * Cost of {@link org.apache.hadoop.fs.s3a.impl.StatusProbeEnum#FILE}.
   */
  public static final OperationCost FILE_STATUS_FILE_PROBE = HEAD_OPERATION;

  /**
   * Cost of {@link org.apache.hadoop.fs.s3a.impl.StatusProbeEnum#ALL}.
   */
  public static final OperationCost FILE_STATUS_ALL_PROBES =
      FILE_STATUS_FILE_PROBE.plus(FILE_STATUS_DIR_PROBE);

  /** getFileStatus() on a file which exists. */
  public static final OperationCost GET_FILE_STATUS_ON_FILE =
      FILE_STATUS_FILE_PROBE;

  /** List costs for getFileStatus() on a non-empty directory: {@value}. */
  public static final OperationCost GET_FILE_STATUS_ON_DIR =
      FILE_STATUS_FILE_PROBE.plus(FILE_STATUS_DIR_PROBE);

  /** Costs for getFileStatus() on an empty directory: {@value}. */
  public static final OperationCost GET_FILE_STATUS_ON_EMPTY_DIR =
      GET_FILE_STATUS_ON_DIR;

  /** getFileStatus() directory marker which exists. */
  public static final OperationCost GET_FILE_STATUS_ON_DIR_MARKER =
      GET_FILE_STATUS_ON_EMPTY_DIR;

  /** getFileStatus() call which fails to find any entry. */
  public static final OperationCost GET_FILE_STATUS_FNFE =
      FILE_STATUS_ALL_PROBES;

  /** listLocatedStatus always does a LIST. */
  public static final OperationCost LIST_LOCATED_STATUS_LIST_OP =
      new OperationCost(0, 1);

  /** listFiles always does a LIST. */
  public static final OperationCost LIST_FILES_LIST_OP =
      new OperationCost(0, 1);

  /**
   * Metadata cost of a copy operation, as used during rename.
   * This happens even if the store is guarded.
   */
  public static final OperationCost COPY_OP =
      new OperationCost(1, 0);

  /**
   * Cost of renaming a file to a different directory.
   * <p></p>
   * LIST on dest not found, look for dest dir, and then, at
   * end of rename, whether a parent dir needs to be created.
   */
  public static final OperationCost RENAME_SINGLE_FILE_DIFFERENT_DIR =
      FILE_STATUS_FILE_PROBE              // source file probe
          .plus(GET_FILE_STATUS_FNFE)     // dest does not exist
          .plus(FILE_STATUS_DIR_PROBE)    // parent dir of dest
          .plus(FILE_STATUS_DIR_PROBE)    // recreate source parent dir?
          .plus(COPY_OP);                 // metadata read on copy

  /**
   * Cost of renaming a file to the same directory
   * <p></p>
   * No need to look for parent directories, so only file
   * existence checks and the copy.
   */
  public static final OperationCost RENAME_SINGLE_FILE_SAME_DIR =
      FILE_STATUS_FILE_PROBE              // source file probe
          .plus(GET_FILE_STATUS_FNFE)     // dest must not exist
          .plus(COPY_OP);                 // metadata read on copy

  /**
   * create(overwrite = true) does not look for the file existing.
   */
  public static final OperationCost CREATE_FILE_OVERWRITE =
      FILE_STATUS_DIR_PROBE;

  /**
   * create(overwrite = false) runs all the checks.
   */
  public static final OperationCost CREATE_FILE_NO_OVERWRITE =
      FILE_STATUS_ALL_PROBES;

  /** Expected HEAD count. */
  private final int head;

  /** Expected LIST count. */
  private final int list;

  /**
   * Constructor.
   * @param head head requests.
   * @param list list requests.
   */
  public OperationCost(final int head,
      final int list) {
    this.head = head;
    this.list = list;
  }

  /** Expected HEAD count. */
  int head() {
    return head;
  }

  /** Expected LIST count. */
  int list() {
    return list;
  }

  /**
   * Add to create a new cost.
   * @param that the other entry
   * @return cost of the combined operation.
   */
  public OperationCost plus(OperationCost that) {
    return new OperationCost(
        head + that.head,
        list + that.list);
  }

  @Override
  public String toString() {
    return "OperationCost{" +
        "head=" + head +
        ", list=" + list +
        '}';
  }
}
