/*
 * 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.LinkedHashMap;
import org.apache.lucene.benchmark.byTask.PerfRunData;
import org.apache.lucene.benchmark.byTask.stats.Report;
import org.apache.lucene.benchmark.byTask.stats.TaskStats;
import org.apache.lucene.benchmark.byTask.utils.Format;

/** Report (abstract) task - all report tasks extend this task. */
public abstract class ReportTask extends PerfTask {

  public ReportTask(PerfRunData runData) {
    super(runData);
  }

  /* (non-Javadoc)
   * @see PerfTask#shouldNeverLogAtStart()
   */
  @Override
  protected boolean shouldNeverLogAtStart() {
    return true;
  }

  /* (non-Javadoc)
   * @see PerfTask#shouldNotRecordStats()
   */
  @Override
  protected boolean shouldNotRecordStats() {
    return true;
  }

  /*
   * From here start the code used to generate the reports.
   * Subclasses would use this part to generate reports.
   */

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

  /** Get a textual summary of the benchmark results, average from all test runs. */
  protected static final String OP = "Operation  ";

  protected static final String ROUND = " round";
  protected static final String RUNCNT = "   runCnt";
  protected static final String RECCNT = "   recsPerRun";
  protected static final String RECSEC = "        rec/s";
  protected static final String ELAPSED = "  elapsedSec";
  protected static final String USEDMEM = "    avgUsedMem";
  protected static final String TOTMEM = "    avgTotalMem";
  protected static final String COLS[] = {RUNCNT, RECCNT, RECSEC, ELAPSED, USEDMEM, TOTMEM};

  /**
   * Compute a title line for a report table
   *
   * @param longestOp size of longest op name in the table
   * @return the table title line.
   */
  protected String tableTitle(String longestOp) {
    StringBuilder sb = new StringBuilder();
    sb.append(Format.format(OP, longestOp));
    sb.append(ROUND);
    sb.append(getRunData().getConfig().getColsNamesForValsByRound());
    for (int i = 0; i < COLS.length; i++) {
      sb.append(COLS[i]);
    }
    return sb.toString();
  }

  /**
   * find the longest op name out of completed tasks.
   *
   * @param taskStats completed tasks to be considered.
   * @return the longest op name out of completed tasks.
   */
  protected String longestOp(Iterable<TaskStats> taskStats) {
    String longest = OP;
    for (final TaskStats stat : taskStats) {
      if (stat.getElapsed() >= 0) { // consider only tasks that ended
        String name = stat.getTask().getName();
        if (name.length() > longest.length()) {
          longest = name;
        }
      }
    }
    return longest;
  }

  /**
   * Compute a report line for the given task stat.
   *
   * @param longestOp size of longest op name in the table.
   * @param stat task stat to be printed.
   * @return the report line.
   */
  protected String taskReportLine(String longestOp, TaskStats stat) {
    PerfTask task = stat.getTask();
    StringBuilder sb = new StringBuilder();
    sb.append(Format.format(task.getName(), longestOp));
    String round = (stat.getRound() >= 0 ? "" + stat.getRound() : "-");
    sb.append(Format.formatPaddLeft(round, ROUND));
    sb.append(getRunData().getConfig().getColsValuesForValsByRound(stat.getRound()));
    sb.append(Format.format(stat.getNumRuns(), RUNCNT));
    sb.append(Format.format(stat.getCount() / stat.getNumRuns(), RECCNT));
    long elapsed = (stat.getElapsed() > 0 ? stat.getElapsed() : 1); // assume at least 1ms
    sb.append(Format.format(2, (float) (stat.getCount() * 1000.0 / elapsed), RECSEC));
    sb.append(Format.format(2, (float) stat.getElapsed() / 1000, ELAPSED));
    sb.append(Format.format(0, (float) stat.getMaxUsedMem() / stat.getNumRuns(), USEDMEM));
    sb.append(Format.format(0, (float) stat.getMaxTotMem() / stat.getNumRuns(), TOTMEM));
    return sb.toString();
  }

  protected Report genPartialReport(
      int reported, LinkedHashMap<String, TaskStats> partOfTasks, int totalSize) {
    String longetOp = longestOp(partOfTasks.values());
    boolean first = true;
    StringBuilder sb = new StringBuilder();
    sb.append(tableTitle(longetOp));
    sb.append(newline);
    int lineNum = 0;
    for (final TaskStats stat : partOfTasks.values()) {
      if (!first) {
        sb.append(newline);
      }
      first = false;
      String line = taskReportLine(longetOp, stat);
      lineNum++;
      if (partOfTasks.size() > 2 && lineNum % 2 == 0) {
        line = line.replaceAll("   ", " - ");
      }
      sb.append(line);
      int[] byTime = stat.getCountsByTime();
      if (byTime != null) {
        sb.append(newline);
        int end = -1;
        for (int i = byTime.length - 1; i >= 0; i--) {
          if (byTime[i] != 0) {
            end = i;
            break;
          }
        }
        if (end != -1) {
          sb.append("  by time:");
          for (int i = 0; i < end; i++) {
            sb.append(' ').append(byTime[i]);
          }
        }
      }
    }

    String reptxt = (reported == 0 ? "No Matching Entries Were Found!" : sb.toString());
    return new Report(reptxt, partOfTasks.size(), reported, totalSize);
  }
}
