// Copyright 2017 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 static com.google.common.base.Preconditions.checkState;

import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableList;
import java.time.Duration;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;

/** Holds the result(s) of an action's execution. */
@AutoValue
public abstract class ActionResult {

  /** An empty ActionResult used by Actions that don't have any metadata to return. */
  public static final ActionResult EMPTY = ActionResult.create(ImmutableList.of());

  /** Returns the SpawnResults for the action. */
  public abstract List<SpawnResult> spawnResults();

  /** Returns a builder that can be used to construct a {@link ActionResult} object. */
  public static Builder builder() {
    return new AutoValue_ActionResult.Builder();
  }

  /**
   * Returns the cumulative time taken by a series of {@link SpawnResult}s.
   *
   * @param getSpawnResultExecutionTime a selector that returns either the wall, user or system time
   *     for each {@link SpawnResult} being considered
   * @return the cumulative time, or empty if no spawn results contained this time
   */
  private Optional<Duration> getCumulativeTime(
      Function<SpawnResult, Optional<Duration>> getSpawnResultExecutionTime) {
    Long totalMillis = null;
    for (SpawnResult spawnResult : spawnResults()) {
      Optional<Duration> executionTime = getSpawnResultExecutionTime.apply(spawnResult);
      if (executionTime.isPresent()) {
        if (totalMillis == null) {
          totalMillis = executionTime.get().toMillis();
        } else {
          totalMillis += executionTime.get().toMillis();
        }
      }
    }
    if (totalMillis == null) {
      return Optional.empty();
    } else {
      return Optional.of(Duration.ofMillis(totalMillis));
    }
  }

  /**
   * Returns the cumulative total of long values taken from a series of {@link SpawnResult}s.
   *
   * @param getSpawnResultLongValue a selector that returns a long value for each {@link
   *     SpawnResult} being considered
   * @return the total, or empty if no spawn results contained this long value
   */
  private Optional<Long> getCumulativeLong(
      Function<SpawnResult, Optional<Long>> getSpawnResultLongValue) {
    Long longTotal = null;
    for (SpawnResult spawnResult : spawnResults()) {
      Optional<Long> longValue = getSpawnResultLongValue.apply(spawnResult);
      if (longValue.isPresent()) {
        if (longTotal == null) {
          longTotal = longValue.get();
        } else {
          longTotal += longValue.get();
        }
      }
    }
    if (longTotal == null) {
      return Optional.empty();
    } else {
      return Optional.of(longTotal);
    }
  }

  /**
   * Returns the cumulative command execution wall time for the {@link Action}.
   *
   * @return the cumulative measurement, or empty in case of execution errors or when the
   *     measurement is not implemented for the current platform
   */
  public Optional<Duration> cumulativeCommandExecutionWallTime() {
    return getCumulativeTime(spawnResult -> spawnResult.getWallTime());
  }

  /**
   * Returns the cumulative command execution user time for the {@link Action}.
   *
   * @return the cumulative measurement, or empty in case of execution errors or when the
   *     measurement is not implemented for the current platform
   */
  public Optional<Duration> cumulativeCommandExecutionUserTime() {
    return getCumulativeTime(spawnResult -> spawnResult.getUserTime());
  }

  /**
   * Returns the cumulative command execution system time for the {@link Action}.
   *
   * @return the cumulative measurement, or empty in case of execution errors or when the
   *     measurement is not implemented for the current platform
   */
  public Optional<Duration> cumulativeCommandExecutionSystemTime() {
    return getCumulativeTime(spawnResult -> spawnResult.getSystemTime());
  }

  /**
   * Returns the cumulative number of block input operations for the {@link Action}.
   *
   * @return the cumulative measurement, or empty in case of execution errors or when the
   *     measurement is not implemented for the current platform
   */
  public Optional<Long> cumulativeCommandExecutionBlockInputOperations() {
    return getCumulativeLong(spawnResult -> spawnResult.getNumBlockInputOperations());
  }

  /**
   * Returns the cumulative number of block output operations for the {@link Action}.
   *
   * @return the cumulative measurement, or empty in case of execution errors or when the
   *     measurement is not implemented for the current platform
   */
  public Optional<Long> cumulativeCommandExecutionBlockOutputOperations() {
    return getCumulativeLong(spawnResult -> spawnResult.getNumBlockOutputOperations());
  }

  /**
   * Returns the cumulative number of involuntary context switches for the {@link Action}.
   *
   * @return the cumulative measurement, or empty in case of execution errors or when the
   *     measurement is not implemented for the current platform
   */
  public Optional<Long> cumulativeCommandExecutionInvoluntaryContextSwitches() {
    return getCumulativeLong(spawnResult -> spawnResult.getNumInvoluntaryContextSwitches());
  }

  /**
   * Returns the cumulative command execution CPU time for the {@link Action}.
   *
   * @return the cumulative measurement, or empty in case of execution errors or when the
   *     measurement is not implemented for the current platform
   */
  public Optional<Duration> cumulativeCommandExecutionCpuTime() {
    Optional<Duration> userTime = cumulativeCommandExecutionUserTime();
    Optional<Duration> systemTime = cumulativeCommandExecutionSystemTime();

    if (!userTime.isPresent() && !systemTime.isPresent()) {
      return Optional.empty();
    } else if (userTime.isPresent() && !systemTime.isPresent()) {
      return userTime;
    } else if (!userTime.isPresent() && systemTime.isPresent()) {
      return systemTime;
    } else {
      checkState(userTime.isPresent() && systemTime.isPresent());
      return Optional.of(userTime.get().plus(systemTime.get()));
    }
  }

  /** Creates an ActionResult given a list of SpawnResults. */
  public static ActionResult create(List<SpawnResult> spawnResults) {
    if (spawnResults == null) {
      return EMPTY;
    } else {
      return builder().setSpawnResults(spawnResults).build();
    }
  }

  /** Builder for a {@link ActionResult} instance, which is immutable once built. */
  @AutoValue.Builder
  public abstract static class Builder {

    /** Sets the SpawnResults for the action. */
    public abstract Builder setSpawnResults(List<SpawnResult> spawnResults);

    /** Builds and returns an ActionResult object. */
    public abstract ActionResult build();
  }
}
