// Copyright 2018 The Bazel Authors. All rights reserved.
//
// Licensed 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 com.google.devtools.build.lib.actions;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/** Timing, size, and memory statistics for a Spawn execution. */
public final class SpawnMetrics {

  /** Indicates whether the metrics correspond to the remote, local or worker execution. */
  public static enum ExecKind {
    REMOTE("Remote"),
    LOCAL("Local"),
    WORKER("Worker"),
    /**
     * Other kinds of execution (or when it's not clear whether something happened locally or
     * remotely).
     */
    OTHER("Other");

    private final String name;

    private ExecKind(String name) {
      this.name = name;
    }

    @Override
    public String toString() {
      return name;
    }
  }

  /** Any non important stats < than 10% will not be shown in the summary. */
  private static final double STATS_SHOW_THRESHOLD = 0.10;

  public static SpawnMetrics forLocalExecution(Duration wallTime) {
    return Builder.forLocalExec().setTotalTime(wallTime).setExecutionWallTime(wallTime).build();
  }

  private final ExecKind execKind;
  private final Duration totalTime;
  private final Duration parseTime;
  private final Duration fetchTime;
  private final Duration queueTime;
  private final Duration uploadTime;
  private final Duration setupTime;
  private final Duration executionWallTime;
  private final Duration processOutputsTime;
  private final Duration networkTime;
  private final Map<Integer, Duration> retryTime;
  private final long inputBytes;
  private final long inputFiles;
  private final long memoryEstimateBytes;

  private SpawnMetrics(Builder builder) {
    this.execKind = builder.execKind;
    this.totalTime = builder.totalTime;
    this.parseTime = builder.parseTime;
    this.networkTime = builder.networkTime;
    this.fetchTime = builder.fetchTime;
    this.queueTime = builder.queueTime;
    this.setupTime = builder.setupTime;
    this.uploadTime = builder.uploadTime;
    this.executionWallTime = builder.executionWallTime;
    this.retryTime = builder.retryTime;
    this.processOutputsTime = builder.processOutputsTime;
    this.inputBytes = builder.inputBytes;
    this.inputFiles = builder.inputFiles;
    this.memoryEstimateBytes = builder.memoryEstimateBytes;
  }

  /** The kind of execution the metrics refer to (remote/local/worker). */
  public ExecKind execKind() {
    return execKind;
  }

  /** Returns true if {@link #totalTime()} is zero. */
  public boolean isEmpty() {
    return totalTime.isZero();
  }

  /**
   * Total (measured locally) wall time spent running a spawn. This should be at least as large as
   * all the other times summed together.
   */
  public Duration totalTime() {
    return totalTime;
  }

  /**
   * Total time spent getting on network. This includes time getting network-side errors and the
   * time of the round-trip, found by taking the difference of wall time here and the server time
   * reported by the RPC. This is 0 for locally executed spawns.
   */
  public Duration networkTime() {
    return networkTime;
  }

  /** Total time waiting in queues. Includes queue time for any failed attempts. */
  public Duration queueTime() {
    return queueTime;
  }

  /** The time spent transferring files to the backends. This is 0 for locally executed spawns. */
  public Duration uploadTime() {
    return uploadTime;
  }

  /**
   * The time required to setup the environment in which the spawn is run. This may be 0 for locally
   * executed spawns, or may include time to setup a sandbox or other environment. Does not include
   * failed attempts.
   */
  public Duration setupTime() {
    return setupTime;
  }

  /** Time spent running the subprocess. */
  public Duration executionWallTime() {
    return executionWallTime;
  }

  /**
   * The time taken to convert the spawn into a network request, e.g., collecting runfiles, and
   * digests for all input files.
   */
  public Duration parseTime() {
    return parseTime;
  }

  /** Total time spent fetching remote outputs. */
  public Duration fetchTime() {
    return fetchTime;
  }

  /** Time spent in previous failed attempts. Does not include queue time. */
  public Duration retryTime() {
    return retryTime.values().stream().reduce(Duration.ZERO, Duration::plus);
  }

  /** Time spent in previous failed attempts, keyed by error code. Does not include queue time. */
  public Map<Integer, Duration> retryTimeByError() {
    return retryTime;
  }


  /** Time spend by the execution framework on processing outputs. */
  public Duration processOutputsTime() {
    return processOutputsTime;
  }

  /** Any time that is not measured by a more specific component, out of {@code totalTime()}. */
  public Duration otherTime() {
    return totalTime
        .minus(parseTime)
        .minus(networkTime)
        .minus(queueTime)
        .minus(uploadTime)
        .minus(setupTime)
        .minus(executionWallTime)
        .minus(fetchTime)
        .minus(retryTime())
        .minus(processOutputsTime);
  }

  /** Total size in bytes of inputs or 0 if unavailable. */
  public long inputBytes() {
    return inputBytes;
  }

  /** Total number of input files or 0 if unavailable. */
  public long inputFiles() {
    return inputFiles;
  }

  /** Estimated memory usage or 0 if unavailable. */
  public long memoryEstimate() {
    return memoryEstimateBytes;
  }

  /**
   * Generates a String representation of the stats.
   *
   * @param total total time used to compute the percentages
   * @param summary whether to exclude input file count and sizes, and memory estimates
   */
  public String toString(Duration total, boolean summary) {
    StringBuilder sb = new StringBuilder();
    sb.append("(");
    sb.append(prettyPercentage(totalTime, total));
    sb.append(" of the time): [");
    List<String> stats = new ArrayList<>(8);
    addStatToString(stats, "parse", !summary, parseTime, total);
    addStatToString(stats, "queue", true, queueTime, total);
    addStatToString(stats, "network", !summary, networkTime, total);
    addStatToString(stats, "upload", !summary, uploadTime, total);
    addStatToString(stats, "setup", true, setupTime, total);
    addStatToString(stats, "process", true, executionWallTime, total);
    addStatToString(stats, "fetch", !summary, fetchTime, total);
    addStatToString(stats, "retry", !summary, retryTime(), total);
    addStatToString(stats, "processOutputs", !summary, processOutputsTime, total);
    addStatToString(stats, "other", !summary, otherTime(), total);
    if (!summary) {
      stats.add("input files: " + inputFiles);
      stats.add("input bytes: " + inputBytes);
      stats.add("memory bytes: " + memoryEstimateBytes);
    }
    Joiner.on(", ").appendTo(sb, stats);
    sb.append("]");
    return sb.toString();
  }

  /**
   * Add to {@code strings} the string representation of {@code name} component. If {@code
   * forceShow} is set to false it will only show if it is above certain threshold.
   */
  private static void addStatToString(
      List<String> strings, String name, boolean forceShow, Duration time, Duration totalTime) {
    if (forceShow || isAboveThreshold(time, totalTime)) {
      strings.add(name + ": " + prettyPercentage(time, totalTime));
    }
  }

  private static boolean isAboveThreshold(Duration time, Duration totalTime) {
    return totalTime.toMillis() > 0
        && (((float) time.toMillis() / totalTime.toMillis()) >= STATS_SHOW_THRESHOLD);
  }

  /**
   * Converts relative duration to the percentage string.
   *
   * @return formatted percentage string or "N/A" if result is undefined
   */
  private static String prettyPercentage(Duration duration, Duration total) {
    // Duration.toMillis() != 0 does not imply !Duration.isZero() (due to truncation).
    if (total.toMillis() == 0) {
      // Return "not available" string if total is 0 and result is undefined.
      return "N/A";
    }
    return String.format("%.2f%%", duration.toMillis() * 100.0 / total.toMillis());
  }

  /** Builder class for SpawnMetrics. */
  public static class Builder {
    private ExecKind execKind = null;
    private Duration totalTime = Duration.ZERO;
    private Duration parseTime = Duration.ZERO;
    private Duration networkTime = Duration.ZERO;
    private Duration fetchTime = Duration.ZERO;
    private Duration queueTime = Duration.ZERO;
    private Duration setupTime = Duration.ZERO;
    private Duration uploadTime = Duration.ZERO;
    private Duration executionWallTime = Duration.ZERO;
    private Duration processOutputsTime = Duration.ZERO;
    private Map<Integer, Duration> retryTime = new HashMap<>();
    private long inputBytes = 0;
    private long inputFiles = 0;
    private long memoryEstimateBytes = 0;

    public static Builder forLocalExec() {
      return forExec(ExecKind.LOCAL);
    }

    public static Builder forRemoteExec() {
      return forExec(ExecKind.REMOTE);
    }

    public static Builder forWorkerExec() {
      return forExec(ExecKind.WORKER);
    }

    public static Builder forOtherExec() {
      return forExec(ExecKind.OTHER);
    }

    public static Builder forExec(ExecKind kind) {
      return new Builder().setExecKind(kind);
    }

    // Make the constructor private to force users to set the ExecKind by using one of the factory
    // methods.
    private Builder() {}

    public SpawnMetrics build() {
      Preconditions.checkNotNull(execKind, "ExecKind must be explicitly set using `setExecKind`");
      // TODO(ulfjack): Add consistency checks here?
      return new SpawnMetrics(this);
    }

    public Builder setExecKind(ExecKind execKind) {
      this.execKind = execKind;
      return this;
    }

    public Builder setTotalTime(Duration totalTime) {
      this.totalTime = totalTime;
      return this;
    }

    public Builder setParseTime(Duration parseTime) {
      this.parseTime = parseTime;
      return this;
    }

    public Builder setNetworkTime(Duration networkTime) {
      this.networkTime = networkTime;
      return this;
    }

    public Builder setFetchTime(Duration fetchTime) {
      this.fetchTime = fetchTime;
      return this;
    }

    public Builder setQueueTime(Duration queueTime) {
      this.queueTime = queueTime;
      return this;
    }

    public Builder setSetupTime(Duration setupTime) {
      this.setupTime = setupTime;
      return this;
    }

    public Builder setUploadTime(Duration uploadTime) {
      this.uploadTime = uploadTime;
      return this;
    }

    public Builder setExecutionWallTime(Duration executionWallTime) {
      this.executionWallTime = executionWallTime;
      return this;
    }

    public Builder addRetryTime(int errorCode, Duration retryTime) {
      Duration d = this.retryTime.getOrDefault(errorCode, Duration.ZERO);
      this.retryTime.put(errorCode, d.plus(retryTime));
      return this;
    }

    public Builder setRetryTime(Map<Integer, Duration> retryTime) {
      this.retryTime = new HashMap<>(retryTime);
      return this;
    }

    public Builder setProcessOutputsTime(Duration processOutputsTime) {
      this.processOutputsTime = processOutputsTime;
      return this;
    }

    public Builder setInputBytes(long inputBytes) {
      this.inputBytes = inputBytes;
      return this;
    }

    public Builder setInputFiles(long inputFiles) {
      this.inputFiles = inputFiles;
      return this;
    }

    public Builder setMemoryEstimateBytes(long memoryEstimateBytes) {
      this.memoryEstimateBytes = memoryEstimateBytes;
      return this;
    }

    public Builder addDurations(SpawnMetrics metric) {
      totalTime = totalTime.plus(metric.totalTime());
      parseTime = parseTime.plus(metric.parseTime());
      networkTime = networkTime.plus(metric.networkTime());
      fetchTime = fetchTime.plus(metric.fetchTime());
      queueTime = queueTime.plus(metric.queueTime());
      uploadTime = uploadTime.plus(metric.uploadTime());
      setupTime = setupTime.plus(metric.setupTime());
      executionWallTime = executionWallTime.plus(metric.executionWallTime());
      for (Map.Entry<Integer, Duration> entry : metric.retryTime.entrySet()) {
        addRetryTime(entry.getKey().intValue(), entry.getValue());
      }
      processOutputsTime = processOutputsTime.plus(metric.processOutputsTime());
      return this;
    }

    public Builder addNonDurations(SpawnMetrics metric) {
      inputFiles += metric.inputFiles();
      inputBytes += metric.inputBytes();
      memoryEstimateBytes += metric.memoryEstimate();
      return this;
    }

    public Builder maxNonDurations(SpawnMetrics metric) {
      inputFiles = Long.max(inputFiles, metric.inputFiles());
      inputBytes = Long.max(inputBytes, metric.inputBytes());
      memoryEstimateBytes = Long.max(memoryEstimateBytes, metric.memoryEstimate());
      return this;
    }
  }
}
