/*
 * 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.lucene.benchmark.byTask.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.StringTokenizer;

/**
 * Perf run configuration properties.
 *
 * <p>Numeric property containing ":", e.g. "10:100:5" is interpreted as array of numeric values. It
 * is extracted once, on first use, and maintain a round number to return the appropriate value.
 *
 * <p>The config property "work.dir" tells where is the root of docs data dirs and indexes dirs. It
 * is set to either of:
 *
 * <ul>
 *   <li>value supplied for it in the alg file;
 *   <li>otherwise, value of System property "benchmark.work.dir";
 *   <li>otherwise, "work".
 * </ul>
 */
public class Config {

  // For tests, if verbose is not turned on, don't print the props.
  private static final String DEFAULT_PRINT_PROPS = System.getProperty("tests.verbose", "true");
  private static final String NEW_LINE = System.getProperty("line.separator");

  private int roundNumber = 0;
  private Properties props;
  private HashMap<String, Object> valByRound = new HashMap<>();
  private HashMap<String, String> colForValByRound = new HashMap<>();
  private String algorithmText;

  /**
   * Read both algorithm and config properties.
   *
   * @param algReader from where to read algorithm and config properties.
   * @throws IOException If there is a low-level I/O error.
   */
  public Config(Reader algReader) throws IOException {
    // read alg file to array of lines
    ArrayList<String> lines = new ArrayList<>();
    BufferedReader r = new BufferedReader(algReader);
    int lastConfigLine = 0;
    for (String line = r.readLine(); line != null; line = r.readLine()) {
      lines.add(line);
      if (line.indexOf('=') > 0) {
        lastConfigLine = lines.size();
      }
    }
    r.close();
    // copy props lines to string
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < lastConfigLine; i++) {
      sb.append(lines.get(i));
      sb.append(NEW_LINE);
    }
    // read props from string
    this.props = new Properties();
    props.load(new StringReader(sb.toString()));

    // make sure work dir is set properly
    if (props.get("work.dir") == null) {
      props.setProperty("work.dir", System.getProperty("benchmark.work.dir", "work"));
    }

    if (Boolean.valueOf(props.getProperty("print.props", DEFAULT_PRINT_PROPS)).booleanValue()) {
      printProps();
    }

    // copy algorithm lines
    sb = new StringBuilder();
    for (int i = lastConfigLine; i < lines.size(); i++) {
      sb.append(lines.get(i));
      sb.append(NEW_LINE);
    }
    algorithmText = sb.toString();
  }

  /**
   * Create config without algorithm - useful for a programmatic perf test.
   *
   * @param props - configuration properties.
   */
  public Config(Properties props) {
    this.props = props;
    if (Boolean.valueOf(props.getProperty("print.props", DEFAULT_PRINT_PROPS)).booleanValue()) {
      printProps();
    }
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private void printProps() {
    System.out.println("------------> config properties:");
    List<String> propKeys = new ArrayList(props.keySet());
    Collections.sort(propKeys);
    for (final String propName : propKeys) {
      System.out.println(propName + " = " + props.getProperty(propName));
    }
    System.out.println("-------------------------------");
  }

  /**
   * Return a string property.
   *
   * @param name name of property.
   * @param dflt default value.
   * @return a string property.
   */
  public String get(String name, String dflt) {
    String vals[] = (String[]) valByRound.get(name);
    if (vals != null) {
      return vals[roundNumber % vals.length];
    }
    // done if not by round
    String sval = props.getProperty(name, dflt);
    if (sval == null) {
      return null;
    }
    if (sval.indexOf(":") < 0) {
      return sval;
    } else if (sval.indexOf(":\\") >= 0 || sval.indexOf(":/") >= 0) {
      // this previously messed up absolute path names on Windows. Assuming
      // there is no real value that starts with \ or /
      return sval;
    }
    // first time this prop is extracted by round
    int k = sval.indexOf(":");
    String colName = sval.substring(0, k);
    sval = sval.substring(k + 1);
    colForValByRound.put(name, colName);
    vals = propToStringArray(sval);
    valByRound.put(name, vals);
    return vals[roundNumber % vals.length];
  }

  /**
   * Set a property. Note: once a multiple values property is set, it can no longer be modified.
   *
   * @param name name of property.
   * @param value either single or multiple property value (multiple values are separated by ":")
   */
  public void set(String name, String value) throws Exception {
    if (valByRound.get(name) != null) {
      throw new Exception("Cannot modify a multi value property!");
    }
    props.setProperty(name, value);
  }

  /**
   * Return an int property. If the property contain ":", e.g. "10:100:5", it is interpreted as
   * array of ints. It is extracted once, on first call to get() it, and a by-round-value is
   * returned.
   *
   * @param name name of property
   * @param dflt default value
   * @return a int property.
   */
  public int get(String name, int dflt) {
    // use value by round if already parsed
    int vals[] = (int[]) valByRound.get(name);
    if (vals != null) {
      return vals[roundNumber % vals.length];
    }
    // done if not by round
    String sval = props.getProperty(name, "" + dflt);
    if (sval.indexOf(":") < 0) {
      return Integer.parseInt(sval);
    }
    // first time this prop is extracted by round
    int k = sval.indexOf(":");
    String colName = sval.substring(0, k);
    sval = sval.substring(k + 1);
    colForValByRound.put(name, colName);
    vals = propToIntArray(sval);
    valByRound.put(name, vals);
    return vals[roundNumber % vals.length];
  }

  /**
   * Return a double property. If the property contain ":", e.g. "10:100:5", it is interpreted as
   * array of doubles. It is extracted once, on first call to get() it, and a by-round-value is
   * returned.
   *
   * @param name name of property
   * @param dflt default value
   * @return a double property.
   */
  public double get(String name, double dflt) {
    // use value by round if already parsed
    double vals[] = (double[]) valByRound.get(name);
    if (vals != null) {
      return vals[roundNumber % vals.length];
    }
    // done if not by round
    String sval = props.getProperty(name, "" + dflt);
    if (sval.indexOf(":") < 0) {
      return Double.parseDouble(sval);
    }
    // first time this prop is extracted by round
    int k = sval.indexOf(":");
    String colName = sval.substring(0, k);
    sval = sval.substring(k + 1);
    colForValByRound.put(name, colName);
    vals = propToDoubleArray(sval);
    valByRound.put(name, vals);
    return vals[roundNumber % vals.length];
  }

  /**
   * Return a boolean property. If the property contain ":", e.g. "true.true.false", it is
   * interpreted as array of booleans. It is extracted once, on first call to get() it, and a
   * by-round-value is returned.
   *
   * @param name name of property
   * @param dflt default value
   * @return a int property.
   */
  public boolean get(String name, boolean dflt) {
    // use value by round if already parsed
    boolean vals[] = (boolean[]) valByRound.get(name);
    if (vals != null) {
      return vals[roundNumber % vals.length];
    }
    // done if not by round
    String sval = props.getProperty(name, "" + dflt);
    if (sval.indexOf(":") < 0) {
      return Boolean.valueOf(sval).booleanValue();
    }
    // first time this prop is extracted by round
    int k = sval.indexOf(":");
    String colName = sval.substring(0, k);
    sval = sval.substring(k + 1);
    colForValByRound.put(name, colName);
    vals = propToBooleanArray(sval);
    valByRound.put(name, vals);
    return vals[roundNumber % vals.length];
  }

  /**
   * Increment the round number, for config values that are extracted by round number.
   *
   * @return the new round number.
   */
  public int newRound() {
    roundNumber++;

    StringBuilder sb =
        new StringBuilder("--> Round ").append(roundNumber - 1).append("-->").append(roundNumber);

    // log changes in values
    if (valByRound.size() > 0) {
      sb.append(": ");
      for (final Map.Entry<String, Object> entry : valByRound.entrySet()) {
        final String name = entry.getKey();
        Object a = entry.getValue();
        if (a instanceof int[]) {
          int ai[] = (int[]) a;
          int n1 = (roundNumber - 1) % ai.length;
          int n2 = roundNumber % ai.length;
          sb.append("  ").append(name).append(":").append(ai[n1]).append("-->").append(ai[n2]);
        } else if (a instanceof double[]) {
          double ad[] = (double[]) a;
          int n1 = (roundNumber - 1) % ad.length;
          int n2 = roundNumber % ad.length;
          sb.append("  ").append(name).append(":").append(ad[n1]).append("-->").append(ad[n2]);
        } else if (a instanceof String[]) {
          String ad[] = (String[]) a;
          int n1 = (roundNumber - 1) % ad.length;
          int n2 = roundNumber % ad.length;
          sb.append("  ").append(name).append(":").append(ad[n1]).append("-->").append(ad[n2]);
        } else {
          boolean ab[] = (boolean[]) a;
          int n1 = (roundNumber - 1) % ab.length;
          int n2 = roundNumber % ab.length;
          sb.append("  ").append(name).append(":").append(ab[n1]).append("-->").append(ab[n2]);
        }
      }
    }

    System.out.println();
    System.out.println(sb.toString());
    System.out.println();

    return roundNumber;
  }

  private String[] propToStringArray(String s) {
    if (s.indexOf(":") < 0) {
      return new String[] {s};
    }

    ArrayList<String> a = new ArrayList<>();
    StringTokenizer st = new StringTokenizer(s, ":");
    while (st.hasMoreTokens()) {
      String t = st.nextToken();
      a.add(t);
    }
    return a.toArray(new String[a.size()]);
  }

  // extract properties to array, e.g. for "10:100:5" return int[]{10,100,5}.
  private int[] propToIntArray(String s) {
    if (s.indexOf(":") < 0) {
      return new int[] {Integer.parseInt(s)};
    }

    ArrayList<Integer> a = new ArrayList<>();
    StringTokenizer st = new StringTokenizer(s, ":");
    while (st.hasMoreTokens()) {
      String t = st.nextToken();
      a.add(Integer.valueOf(t));
    }
    int res[] = new int[a.size()];
    for (int i = 0; i < a.size(); i++) {
      res[i] = a.get(i).intValue();
    }
    return res;
  }

  // extract properties to array, e.g. for "10.7:100.4:-2.3" return int[]{10.7,100.4,-2.3}.
  private double[] propToDoubleArray(String s) {
    if (s.indexOf(":") < 0) {
      return new double[] {Double.parseDouble(s)};
    }

    ArrayList<Double> a = new ArrayList<>();
    StringTokenizer st = new StringTokenizer(s, ":");
    while (st.hasMoreTokens()) {
      String t = st.nextToken();
      a.add(Double.valueOf(t));
    }
    double res[] = new double[a.size()];
    for (int i = 0; i < a.size(); i++) {
      res[i] = a.get(i).doubleValue();
    }
    return res;
  }

  // extract properties to array, e.g. for "true:true:false" return boolean[]{true,false,false}.
  private boolean[] propToBooleanArray(String s) {
    if (s.indexOf(":") < 0) {
      return new boolean[] {Boolean.valueOf(s).booleanValue()};
    }

    ArrayList<Boolean> a = new ArrayList<>();
    StringTokenizer st = new StringTokenizer(s, ":");
    while (st.hasMoreTokens()) {
      String t = st.nextToken();
      a.add(Boolean.valueOf(t));
    }
    boolean res[] = new boolean[a.size()];
    for (int i = 0; i < a.size(); i++) {
      res[i] = a.get(i).booleanValue();
    }
    return res;
  }

  /** @return names of params set by round, for reports title */
  public String getColsNamesForValsByRound() {
    if (colForValByRound.size() == 0) {
      return "";
    }
    StringBuilder sb = new StringBuilder();
    for (final String colName : colForValByRound.values()) {
      sb.append(' ').append(colName);
    }
    return sb.toString();
  }

  /** @return values of params set by round, for reports lines. */
  public String getColsValuesForValsByRound(int roundNum) {
    if (colForValByRound.size() == 0) {
      return "";
    }
    StringBuilder sb = new StringBuilder();
    for (final Map.Entry<String, String> entry : colForValByRound.entrySet()) {
      String colName = entry.getValue();
      String template = " " + colName;
      if (roundNum < 0) {
        // just append blanks
        sb.append(Format.formatPaddLeft("-", template));
      } else {
        String valByRoundName = entry.getKey();

        // append actual values, for that round
        Object a = valByRound.get(valByRoundName);
        if (a instanceof int[]) {
          int ai[] = (int[]) a;
          int n = roundNum % ai.length;
          sb.append(Format.format(ai[n], template));
        } else if (a instanceof double[]) {
          double ad[] = (double[]) a;
          int n = roundNum % ad.length;
          sb.append(Format.format(2, ad[n], template));
        } else if (a instanceof String[]) {
          String ad[] = (String[]) a;
          int n = roundNum % ad.length;
          sb.append(ad[n]);
        } else {
          boolean ab[] = (boolean[]) a;
          int n = roundNum % ab.length;
          sb.append(Format.formatPaddLeft("" + ab[n], template));
        }
      }
    }
    return sb.toString();
  }

  /** @return the round number. */
  public int getRoundNumber() {
    return roundNumber;
  }

  /** @return Returns the algorithmText. */
  public String getAlgorithmText() {
    return algorithmText;
  }
}
