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

import java.util.Locale;
import org.apache.lucene.benchmark.byTask.PerfRunData;
import org.apache.lucene.benchmark.byTask.stats.Points;
import org.apache.lucene.benchmark.byTask.stats.TaskStats;
import org.apache.lucene.benchmark.byTask.utils.Config;

/**
 * An abstract task to be tested for performance. <br>
 * Every performance task extends this class, and provides its own {@link #doLogic()} method, which
 * performs the actual task. <br>
 * Tasks performing some work that should be measured for the task, can override {@link #setup()}
 * and/or {@link #tearDown()} and place that work there. <br>
 * Relevant properties: <code>task.max.depth.log</code>.<br>
 * Also supports the following logging attributes:
 *
 * <ul>
 *   <li>log.step - specifies how often to log messages about the current running task. Default is
 *       1000 {@link #doLogic()} invocations. Set to -1 to disable logging.
 *   <li>log.step.[class Task Name] - specifies the same as 'log.step', only for a particular task
 *       name. For example, log.step.AddDoc will be applied only for {@link AddDocTask}. It's a way
 *       to control per task logging settings. If you want to omit logging for any other task,
 *       include log.step=-1. The syntax is "log.step." together with the Task's 'short' name (i.e.,
 *       without the 'Task' part).
 * </ul>
 */
public abstract class PerfTask implements Cloneable {

  static final int DEFAULT_LOG_STEP = 1000;

  private PerfRunData runData;

  // propeties that all tasks have
  private String name;
  private int depth = 0;
  protected int logStep;
  private int logStepCount = 0;
  private int maxDepthLogStart = 0;
  private boolean disableCounting = false;
  protected String params = null;

  private boolean runInBackground;
  private int deltaPri;

  // The first line of this task's definition in the alg file
  private int algLineNum = 0;

  protected static final String NEW_LINE = System.getProperty("line.separator");

  /** Should not be used externally */
  private PerfTask() {
    name = getClass().getSimpleName();
    if (name.endsWith("Task")) {
      name = name.substring(0, name.length() - 4);
    }
  }

  public void setRunInBackground(int deltaPri) {
    runInBackground = true;
    this.deltaPri = deltaPri;
  }

  public boolean getRunInBackground() {
    return runInBackground;
  }

  public int getBackgroundDeltaPriority() {
    return deltaPri;
  }

  protected volatile boolean stopNow;

  public void stopNow() {
    stopNow = true;
  }

  public PerfTask(PerfRunData runData) {
    this();
    this.runData = runData;
    Config config = runData.getConfig();
    this.maxDepthLogStart = config.get("task.max.depth.log", 0);

    String logStepAtt = "log.step";
    String taskLogStepAtt = "log.step." + name;
    if (config.get(taskLogStepAtt, null) != null) {
      logStepAtt = taskLogStepAtt;
    }

    // It's important to read this from Config, to support vals-by-round.
    logStep = config.get(logStepAtt, DEFAULT_LOG_STEP);
    // To avoid the check 'if (logStep > 0)' in tearDown(). This effectively
    // turns logging off.
    if (logStep <= 0) {
      logStep = Integer.MAX_VALUE;
    }
  }

  @Override
  protected PerfTask clone() throws CloneNotSupportedException {
    // tasks having non primitive data structures should override this.
    // otherwise parallel running of a task sequence might not run correctly.
    return (PerfTask) super.clone();
  }

  public void close() throws Exception {}

  /**
   * Run the task, record statistics.
   *
   * @return number of work items done by this task.
   */
  public final int runAndMaybeStats(boolean reportStats) throws Exception {
    if (!reportStats || shouldNotRecordStats()) {
      setup();
      int count = doLogic();
      count = disableCounting ? 0 : count;
      tearDown();
      return count;
    }
    if (reportStats && depth <= maxDepthLogStart && !shouldNeverLogAtStart()) {
      System.out.println("------------> starting task: " + getName());
    }
    setup();
    Points pnts = runData.getPoints();
    TaskStats ts = pnts.markTaskStart(this, runData.getConfig().getRoundNumber());
    int count = doLogic();
    count = disableCounting ? 0 : count;
    pnts.markTaskEnd(ts, count);
    tearDown();
    return count;
  }

  /**
   * Perform the task once (ignoring repetitions specification) Return number of work items done by
   * this task. For indexing that can be number of docs added. For warming that can be number of
   * scanned items, etc.
   *
   * @return number of work items done by this task.
   */
  public abstract int doLogic() throws Exception;

  /** @return Returns the name. */
  public String getName() {
    if (params == null) {
      return name;
    }
    return new StringBuilder(name).append('(').append(params).append(')').toString();
  }

  /** @param name The name to set. */
  protected void setName(String name) {
    this.name = name;
  }

  /** @return Returns the run data. */
  public PerfRunData getRunData() {
    return runData;
  }

  /** @return Returns the depth. */
  public int getDepth() {
    return depth;
  }

  /** @param depth The depth to set. */
  public void setDepth(int depth) {
    this.depth = depth;
  }

  // compute a blank string padding for printing this task indented by its depth
  String getPadding() {
    char c[] = new char[4 * getDepth()];
    for (int i = 0; i < c.length; i++) c[i] = ' ';
    return new String(c);
  }

  @Override
  public String toString() {
    String padd = getPadding();
    StringBuilder sb = new StringBuilder(padd);
    if (disableCounting) {
      sb.append('-');
    }
    sb.append(getName());
    if (getRunInBackground()) {
      sb.append(" &");
      int x = getBackgroundDeltaPriority();
      if (x != 0) {
        sb.append(x);
      }
    }
    return sb.toString();
  }

  /** @return Returns the maxDepthLogStart. */
  int getMaxDepthLogStart() {
    return maxDepthLogStart;
  }

  protected String getLogMessage(int recsCount) {
    return "processed " + recsCount + " records";
  }

  /**
   * Tasks that should never log at start can override this.
   *
   * @return true if this task should never log when it start.
   */
  protected boolean shouldNeverLogAtStart() {
    return false;
  }

  /**
   * Tasks that should not record statistics can override this.
   *
   * @return true if this task should never record its statistics.
   */
  protected boolean shouldNotRecordStats() {
    return false;
  }

  /**
   * Task setup work that should not be measured for that specific task. By default it does nothing,
   * but tasks can implement this, moving work from {@link #doLogic()} to this method. Only the work
   * done in {@link #doLogic()} is measured for this task. Notice that higher level (sequence) tasks
   * containing this task would then measure larger time than the sum of their contained tasks.
   */
  public void setup() throws Exception {}

  /**
   * Task tearDown work that should not be measured for that specific task. By default it does
   * nothing, but tasks can implement this, moving work from {@link #doLogic()} to this method. Only
   * the work done in {@link #doLogic()} is measured for this task. Notice that higher level
   * (sequence) tasks containing this task would then measure larger time than the sum of their
   * contained tasks.
   */
  public void tearDown() throws Exception {
    if (++logStepCount % logStep == 0) {
      double time = (System.currentTimeMillis() - runData.getStartTimeMillis()) / 1000.0;
      System.out.println(
          String.format(Locale.ROOT, "%7.2f", time)
              + " sec --> "
              + Thread.currentThread().getName()
              + " "
              + getLogMessage(logStepCount));
    }
  }

  /**
   * Sub classes that support parameters must override this method to return true.
   *
   * @return true iff this task supports command line params.
   */
  public boolean supportsParams() {
    return false;
  }

  /**
   * Set the params of this task.
   *
   * @exception UnsupportedOperationException for tasks supporting command line parameters.
   */
  public void setParams(String params) {
    if (!supportsParams()) {
      throw new UnsupportedOperationException(
          getName() + " does not support command line parameters.");
    }
    this.params = params;
  }

  /** @return Returns the Params. */
  public String getParams() {
    return params;
  }

  /** Return true if counting is disabled for this task. */
  public boolean isDisableCounting() {
    return disableCounting;
  }

  /** See {@link #isDisableCounting()} */
  public void setDisableCounting(boolean disableCounting) {
    this.disableCounting = disableCounting;
  }

  public void setAlgLineNum(int algLineNum) {
    this.algLineNum = algLineNum;
  }

  public int getAlgLineNum() {
    return algLineNum;
  }
}
