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

import java.text.NumberFormat;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.slive.Constants.OperationType;
import org.apache.hadoop.util.StringUtils;

/**
 * Simple access layer onto of a configuration object that extracts the slive
 * specific configuration values needed for slive running
 */
class ConfigExtractor {

  private static final Log LOG = LogFactory.getLog(ConfigExtractor.class);

  private Configuration config;

  ConfigExtractor(Configuration cfg) {
    this.config = cfg;
  }

  /**
   * @return the wrapped configuration that this extractor will use
   */
  Configuration getConfig() {
    return this.config;
  }

  /**
   * @return the location of where data should be written to
   */
  Path getDataPath() {
    Path base = getBaseDirectory();
    if (base == null) {
      return null;
    }
    return new Path(base, Constants.DATA_DIR);
  }

  /**
   * @return the location of where the reducer should write its data to
   */
  Path getOutputPath() {
    Path base = getBaseDirectory();
    if (base == null) {
      return null;
    }
    return new Path(base, Constants.OUTPUT_DIR);
  }

  /**
   * @param primary
   *          primary the initial string to be used for the value of this
   *          configuration option (if not provided then config and then the
   *          default are used)
   * 
   * @return the base directory where output & data should be stored using
   *         primary,config,default (in that order)
   */
  Path getBaseDirectory(String primary) {
    String path = primary;
    if (path == null) {
      path = config.get(ConfigOption.BASE_DIR.getCfgOption());
    }
    if (path == null) {
      path = ConfigOption.BASE_DIR.getDefault();
    }
    if (path == null) {
      return null;
    }
    return new Path(path);
  }

  /**
   * @return the base directory using only config and default values
   */
  Path getBaseDirectory() {
    return getBaseDirectory(null);
  }

  /**
   * @return whether the mapper or reducer should exit when they get there first
   *         error using only config and default values
   */
  boolean shouldExitOnFirstError() {
    return shouldExitOnFirstError(null);
  }

  /**
   * @param primary
   *          primary the initial string to be used for the value of this
   *          configuration option (if not provided then config and then the
   *          default are used)
   * 
   * @return the boolean of whether the mapper/reducer should exit when they
   *         first error from primary,config,default (in that order)
   */
  boolean shouldExitOnFirstError(String primary) {
    String val = primary;
    if (val == null) {
      val = config.get(ConfigOption.EXIT_ON_ERROR.getCfgOption());
    }
    if (val == null) {
      return ConfigOption.EXIT_ON_ERROR.getDefault();
    }
    return Boolean.parseBoolean(val);
  }

  /**
   * @return the number of reducers to use
   */
  Integer getReducerAmount() {
    // should be slive.reduces
    return getInteger(null, ConfigOption.REDUCES);
  }

  /**
   * @return the number of mappers to use using config and default values for
   *         lookup
   */
  Integer getMapAmount() {
    return getMapAmount(null);
  }

  /**
   * @param primary
   *          primary the initial string to be used for the value of this
   *          configuration option (if not provided then config and then the
   *          default are used)
   * @return the reducer amount to use
   */
  Integer getMapAmount(String primary) {
    return getInteger(primary, ConfigOption.MAPS);
  }

  /**
   * @return the duration in seconds (or null or Integer.MAX for no limit) using
   *         the configuration and default as lookup
   */
  Integer getDuration() {
    return getDuration(null);
  }

  /**
   * @return the duration in milliseconds or null if no limit using config and
   *         default as lookup
   */
  Integer getDurationMilliseconds() {
    Integer seconds = getDuration();
    if (seconds == null || seconds == Integer.MAX_VALUE) {
      return Integer.MAX_VALUE;
    }
    int milliseconds = (seconds * 1000);
    if (milliseconds < 0) {
      milliseconds = 0;
    }
    return milliseconds;
  }

  /**
   * @param primary
   *          primary the initial string to be used for the value of this
   *          configuration option (if not provided then config and then the
   *          default are used)
   * @return the duration in seconds (or null or Integer.MAX for no limit)
   */
  Integer getDuration(String primary) {
    return getInteger(primary, ConfigOption.DURATION);
  }

  /**
   * @return the total number of operations to run using config and default as
   *         lookup
   */
  Integer getOpCount() {
    return getOpCount(null);
  }

  /**
   * @param primary
   *          primary the initial string to be used for the value of this
   *          configuration option (if not provided then config and then the
   *          default are used)
   * @return the total number of operations to run
   */
  Integer getOpCount(String primary) {
    return getInteger(primary, ConfigOption.OPS);
  }

  /**
   * @return the total number of files per directory using config and default as
   *         lookup
   */
  Integer getDirSize() {
    return getDirSize(null);
  }

  /**
   * @param primary
   *          primary the initial string to be used for the value of this
   *          configuration option (if not provided then config and then the
   *          default are used)
   * @return the total number of files per directory
   */
  Integer getDirSize(String primary) {
    return getInteger(primary, ConfigOption.DIR_SIZE);
  }

  /**
   * @param primary
   *          the primary string to attempt to convert into a integer
   * @param opt
   *          the option to use as secondary + default if no primary given
   * @return a parsed integer
   */
  private Integer getInteger(String primary, ConfigOption<Integer> opt) {
    String value = primary;
    if (value == null) {
      value = config.get(opt.getCfgOption());
    }
    if (value == null) {
      return opt.getDefault();
    }
    return Integer.parseInt(value);
  }

  /**
   * @return the total number of files allowed using configuration and default
   *         for lookup
   */
  Integer getTotalFiles() {
    return getTotalFiles(null);
  }

  /**
   * @param primary
   *          primary the initial string to be used for the value of this
   *          configuration option (if not provided then config and then the
   *          default are used)
   * @return the total number of files allowed
   */
  Integer getTotalFiles(String primary) {
    return getInteger(primary, ConfigOption.FILES);
  }

  /**
   * @param primary
   *          primary the initial string to be used for the value of this
   *          configuration option (if not provided then config and then the
   *          default are used)
   * @return the random seed start point or null if none
   */
  Long getRandomSeed(String primary) {
    String seed = primary;
    if (seed == null) {
      seed = config.get(ConfigOption.RANDOM_SEED.getCfgOption());
    }
    if (seed == null) {
      return null;
    }
    return Long.parseLong(seed);
  }

  /**
   * @return the random seed start point or null if none using config and then
   *         default as lookup
   */
  Long getRandomSeed() {
    return getRandomSeed(null);
  }

  /**
   * @return the result file location or null if none using config and then
   *         default as lookup
   */
  String getResultFile() {
    return getResultFile(null);
  }

  /**
   * Gets the grid queue name to run on using config and default only
   * 
   * @return String
   */
  String getQueueName() {
    return getQueueName(null);
  }

  /**
   * Gets the grid queue name to run on using the primary string or config or
   * default
   * 
   * @param primary
   * 
   * @return String
   */
  String getQueueName(String primary) {
    String q = primary;
    if (q == null) {
      q = config.get(ConfigOption.QUEUE_NAME.getCfgOption());
    }
    if (q == null) {
      q = ConfigOption.QUEUE_NAME.getDefault();
    }
    return q;
  }

  /**
   * @param primary
   *          primary the initial string to be used for the value of this
   *          configuration option (if not provided then config and then the
   *          default are used)
   * @return the result file location
   */
  String getResultFile(String primary) {
    String fn = primary;
    if (fn == null) {
      fn = config.get(ConfigOption.RESULT_FILE.getCfgOption());
    }
    if (fn == null) {
      fn = ConfigOption.RESULT_FILE.getDefault();
    }
    return fn;
  }

  /**
   * @param primary
   *          primary the initial string to be used for the value of this
   *          configuration option (if not provided then config and then the
   *          default are used)
   * @return the integer range allowed for the block size
   */
  Range<Long> getBlockSize(String primary) {
    return getMinMaxBytes(ConfigOption.BLOCK_SIZE, primary);
  }

  /**
   * @return the integer range allowed for the block size using config and
   *         default for lookup
   */
  Range<Long> getBlockSize() {
    return getBlockSize(null);
  }

  /**
   * @param cfgopt
   *          the configuration option to use for config and default lookup
   * @param primary
   *          the initial string to be used for the value of this configuration
   *          option (if not provided then config and then the default are used)
   * @return the parsed short range from primary, config, default
   */
  private Range<Short> getMinMaxShort(ConfigOption<Short> cfgopt, String primary) {
    String sval = primary;
    if (sval == null) {
      sval = config.get(cfgopt.getCfgOption());
    }
    Range<Short> range = null;
    if (sval != null) {
      String pieces[] = Helper.getTrimmedStrings(sval);
      if (pieces.length == 2) {
        String min = pieces[0];
        String max = pieces[1];
        short minVal = Short.parseShort(min);
        short maxVal = Short.parseShort(max);
        if (minVal > maxVal) {
          short tmp = minVal;
          minVal = maxVal;
          maxVal = tmp;
        }
        range = new Range<Short>(minVal, maxVal);
      }
    }
    if (range == null) {
      Short def = cfgopt.getDefault();
      if (def != null) {
        range = new Range<Short>(def, def);
      }
    }
    return range;
  }

  /**
   * @param cfgopt
   *          the configuration option to use for config and default lookup
   * @param primary
   *          the initial string to be used for the value of this configuration
   *          option (if not provided then config and then the default are used)
   * @return the parsed long range from primary, config, default
   */
  private Range<Long> getMinMaxLong(ConfigOption<Long> cfgopt, String primary) {
    String sval = primary;
    if (sval == null) {
      sval = config.get(cfgopt.getCfgOption());
    }
    Range<Long> range = null;
    if (sval != null) {
      String pieces[] = Helper.getTrimmedStrings(sval);
      if (pieces.length == 2) {
        String min = pieces[0];
        String max = pieces[1];
        long minVal = Long.parseLong(min);
        long maxVal = Long.parseLong(max);
        if (minVal > maxVal) {
          long tmp = minVal;
          minVal = maxVal;
          maxVal = tmp;
        }
        range = new Range<Long>(minVal, maxVal);
      }
    }
    if (range == null) {
      Long def = cfgopt.getDefault();
      if (def != null) {
        range = new Range<Long>(def, def);
      }
    }
    return range;
  }

  /**
   * @param cfgopt
   *          the configuration option to use for config and default lookup
   * @param primary
   *          the initial string to be used for the value of this configuration
   *          option (if not provided then config and then the default are used)
   * @return the parsed integer byte range from primary, config, default
   */
  private Range<Long> getMinMaxBytes(ConfigOption<Long> cfgopt, String primary) {
    String sval = primary;
    if (sval == null) {
      sval = config.get(cfgopt.getCfgOption());
    }
    Range<Long> range = null;
    if (sval != null) {
      String pieces[] = Helper.getTrimmedStrings(sval);
      if (pieces.length == 2) {
        String min = pieces[0];
        String max = pieces[1];
        long tMin = StringUtils.TraditionalBinaryPrefix.string2long(min);
        long tMax = StringUtils.TraditionalBinaryPrefix.string2long(max);
        if (tMin > tMax) {
          long tmp = tMin;
          tMin = tMax;
          tMax = tmp;
        }
        range = new Range<Long>(tMin, tMax);
      }
    }
    if (range == null) {
      Long def = cfgopt.getDefault();
      if (def != null) {
        range = new Range<Long>(def, def);
      }
    }
    return range;
  }

  /**
   * @param primary
   *          the initial string to be used for the value of this configuration
   *          option (if not provided then config and then the default are used)
   * @return the replication range
   */
  Range<Short> getReplication(String primary) {
    return getMinMaxShort(ConfigOption.REPLICATION_AM, primary);
  }

  /**
   * @return the replication range using config and default for lookup
   */
  Range<Short> getReplication() {
    return getReplication(null);
  }

  /**
   * @return the map of operations to perform using config (percent may be null
   *         if unspecified)
   */
  Map<OperationType, OperationData> getOperations() {
    Map<OperationType, OperationData> operations = new HashMap<OperationType, OperationData>();
    for (OperationType type : OperationType.values()) {
      String opname = type.lowerName();
      String keyname = String.format(Constants.OP, opname);
      String kval = config.get(keyname);
      if (kval == null) {
        continue;
      }
      operations.put(type, new OperationData(kval));
    }
    return operations;
  }

  /**
   * @param primary
   *          the initial string to be used for the value of this configuration
   *          option (if not provided then config and then the default are used)
   * @return the append byte size range (or null if none)
   */
  Range<Long> getAppendSize(String primary) {
    return getMinMaxBytes(ConfigOption.APPEND_SIZE, primary);
  }

  /**
   * @return the append byte size range (or null if none) using config and
   *         default for lookup
   */
  Range<Long> getAppendSize() {
    return getAppendSize(null);
  }

  /**
   * @param primary
   *          the initial string to be used for the value of this configuration
   *          option (if not provided then config and then the default are used)
   * @return the sleep range (or null if none)
   */
  Range<Long> getSleepRange(String primary) {
    return getMinMaxLong(ConfigOption.SLEEP_TIME, primary);
  }

  /**
   * @return the sleep range (or null if none) using config and default for
   *         lookup
   */
  Range<Long> getSleepRange() {
    return getSleepRange(null);
  }

  /**
   * @param primary
   *          the initial string to be used for the value of this configuration
   *          option (if not provided then config and then the default are used)
   * @return the write byte size range (or null if none)
   */
  Range<Long> getWriteSize(String primary) {
    return getMinMaxBytes(ConfigOption.WRITE_SIZE, primary);
  }

  /**
   * @return the write byte size range (or null if none) using config and
   *         default for lookup
   */
  Range<Long> getWriteSize() {
    return getWriteSize(null);
  }

  /**
   * Returns whether the write range should use the block size range
   * 
   * @return true|false
   */
  boolean shouldWriteUseBlockSize() {
    Range<Long> writeRange = getWriteSize();
    if (writeRange == null
        || (writeRange.getLower() == writeRange.getUpper() && (writeRange
            .getUpper() == Long.MAX_VALUE))) {
      return true;
    }
    return false;
  }

  /**
   * Returns whether the append range should use the block size range
   * 
   * @return true|false
   */
  boolean shouldAppendUseBlockSize() {
    Range<Long> appendRange = getAppendSize();
    if (appendRange == null
        || (appendRange.getLower() == appendRange.getUpper() && (appendRange
            .getUpper() == Long.MAX_VALUE))) {
      return true;
    }
    return false;
  }

  /**
   * Returns whether the read range should use the entire file
   * 
   * @return true|false
   */
  boolean shouldReadFullFile() {
    Range<Long> readRange = getReadSize();
    if (readRange == null
        || (readRange.getLower() == readRange.getUpper() && (readRange
            .getUpper() == Long.MAX_VALUE))) {
      return true;
    }
    return false;
  }

  /**
   * @param primary
   *          the initial string to be used for the value of this configuration
   *          option (if not provided then config and then the default are used)
   * @return the read byte size range (or null if none)
   */
  Range<Long> getReadSize(String primary) {
    return getMinMaxBytes(ConfigOption.READ_SIZE, primary);
  }
  
  /**
   * Gets the bytes per checksum (if it exists or null if not)
   * 
   * @return Long 
   */
  Long getByteCheckSum() {
    String val = config.get(Constants.BYTES_PER_CHECKSUM);
    if(val == null) {
      return null;
    }
    return Long.parseLong(val);
  }

  /**
   * @return the read byte size range (or null if none) using config and default
   *         for lookup
   */
  Range<Long> getReadSize() {
    return getReadSize(null);
  }

  /**
   * Dumps out the given options for the given config extractor
   * 
   * @param cfg
   *          the config to write to the log
   */
  static void dumpOptions(ConfigExtractor cfg) {
    if (cfg == null) {
      return;
    }
    LOG.info("Base directory = " + cfg.getBaseDirectory());
    LOG.info("Data directory = " + cfg.getDataPath());
    LOG.info("Output directory = " + cfg.getOutputPath());
    LOG.info("Result file = " + cfg.getResultFile());
    LOG.info("Grid queue = " + cfg.getQueueName());
    LOG.info("Should exit on first error = " + cfg.shouldExitOnFirstError());
    {
      String duration = "Duration = ";
      if (cfg.getDurationMilliseconds() == Integer.MAX_VALUE) {
        duration += "unlimited";
      } else {
        duration += cfg.getDurationMilliseconds() + " milliseconds";
      }
      LOG.info(duration);
    }
    LOG.info("Map amount = " + cfg.getMapAmount());
    LOG.info("Reducer amount = " + cfg.getReducerAmount());
    LOG.info("Operation amount = " + cfg.getOpCount());
    LOG.info("Total file limit = " + cfg.getTotalFiles());
    LOG.info("Total dir file limit = " + cfg.getDirSize());
    {
      String read = "Read size = ";
      if (cfg.shouldReadFullFile()) {
        read += "entire file";
      } else {
        read += cfg.getReadSize() + " bytes";
      }
      LOG.info(read);
    }
    {
      String write = "Write size = ";
      if (cfg.shouldWriteUseBlockSize()) {
        write += "blocksize";
      } else {
        write += cfg.getWriteSize() + " bytes";
      }
      LOG.info(write);
    }
    {
      String append = "Append size = ";
      if (cfg.shouldAppendUseBlockSize()) {
        append += "blocksize";
      } else {
        append += cfg.getAppendSize() + " bytes";
      }
      LOG.info(append);
    }
    {
      String bsize = "Block size = ";
      bsize += cfg.getBlockSize() + " bytes";
      LOG.info(bsize);
    }
    if (cfg.getRandomSeed() != null) {
      LOG.info("Random seed = " + cfg.getRandomSeed());
    }
    if (cfg.getSleepRange() != null) {
      LOG.info("Sleep range = " + cfg.getSleepRange() + " milliseconds");
    }
    LOG.info("Replication amount = " + cfg.getReplication());
    LOG.info("Operations are:");
    NumberFormat percFormatter = Formatter.getPercentFormatter();
    Map<OperationType, OperationData> operations = cfg.getOperations();
    for (OperationType type : operations.keySet()) {
      String name = type.name();
      LOG.info(name);
      OperationData opInfo = operations.get(type);
      LOG.info(" " + opInfo.getDistribution().name());
      if (opInfo.getPercent() != null) {
        LOG.info(" " + percFormatter.format(opInfo.getPercent()));
      } else {
        LOG.info(" ???");
      }
    }
  }

}
