// Copyright 2014 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.skyframe;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import com.google.devtools.build.lib.collect.nestedset.NestedSet;
import com.google.devtools.build.lib.collect.nestedset.NestedSetBuilder;
import com.google.devtools.build.lib.collect.nestedset.Order;
import com.google.devtools.build.lib.util.Preconditions;
import com.google.devtools.build.skyframe.SkyFunctionException.ReifiedSkyFunctionException;

import java.util.Collection;

import javax.annotation.Nullable;

/**
 * Information about why a {@link SkyValue} failed to evaluate successfully.
 *
 * <p>This is intended only for use in alternative {@code MemoizingEvaluator} implementations.
 */
public class ErrorInfo {

  /** Create an ErrorInfo from a {@link ReifiedSkyFunctionException}. */
  public static ErrorInfo fromException(ReifiedSkyFunctionException skyFunctionException,
      boolean isTransitivelyTransient) {
    SkyKey rootCauseSkyKey = skyFunctionException.getRootCauseSkyKey();
    Exception rootCauseException = skyFunctionException.getCause();
    return new ErrorInfo(
        NestedSetBuilder.create(Order.STABLE_ORDER, rootCauseSkyKey),
        Preconditions.checkNotNull(rootCauseException, "Cause null %s", rootCauseException),
        rootCauseSkyKey,
        /*cycles=*/ ImmutableList.<CycleInfo>of(),
        isTransitivelyTransient || skyFunctionException.isTransient(),
        skyFunctionException.isCatastrophic());
  }

  /** Create an ErrorInfo from a {@link CycleInfo}. */
  public static ErrorInfo fromCycle(CycleInfo cycleInfo) {
    return new ErrorInfo(
        /*rootCauses=*/ NestedSetBuilder.<SkyKey>emptySet(Order.STABLE_ORDER),
        /*exception=*/ null,
        /*rootCauseOfException=*/ null,
        ImmutableList.of(cycleInfo),
        /*isTransient=*/ false,
        /*isCatastrophic=*/ false);
  }

  /** Create an ErrorInfo from a collection of existing errors. */
  public static ErrorInfo fromChildErrors(SkyKey currentValue, Collection<ErrorInfo> childErrors) {
    Preconditions.checkNotNull(currentValue, "currentValue must not be null");
    Preconditions.checkState(!childErrors.isEmpty(), "childErrors may not be empty");

    NestedSetBuilder<SkyKey> rootCausesBuilder = NestedSetBuilder.stableOrder();
    ImmutableList.Builder<CycleInfo> cycleBuilder = ImmutableList.builder();
    Exception firstException = null;
    SkyKey firstChildKey = null;
    boolean isTransient = false;
    boolean isCatastrophic = false;
    for (ErrorInfo child : childErrors) {
      if (firstException == null) {
        // Arbitrarily pick the first error.
        firstException = child.getException();
        firstChildKey = child.getRootCauseOfException();
      }
      rootCausesBuilder.addTransitive(child.rootCauses);
      cycleBuilder.addAll(CycleInfo.prepareCycles(currentValue, child.cycles));
      isTransient |= child.isTransient();
      isCatastrophic |= child.isCatastrophic();
    }

    return new ErrorInfo(
        rootCausesBuilder.build(),
        firstException,
        firstChildKey,
        cycleBuilder.build(),
        isTransient,
        isCatastrophic);
  }

  private final NestedSet<SkyKey> rootCauses;

  @Nullable private final Exception exception;
  private final SkyKey rootCauseOfException;

  private final ImmutableList<CycleInfo> cycles;

  private final boolean isTransient;
  private final boolean isCatastrophic;

  public ErrorInfo(NestedSet<SkyKey> rootCauses, @Nullable Exception exception,
      SkyKey rootCauseOfException, ImmutableList<CycleInfo> cycles, boolean isTransient,
      boolean isCatostrophic) {
    Preconditions.checkState(exception != null || !Iterables.isEmpty(cycles),
        "At least one of exception and cycles must be non-null/empty, respectively");
    Preconditions.checkState((exception == null) == (rootCauseOfException == null),
        "exception and rootCauseOfException must both be null or non-null, got %s  %s",
        exception, rootCauseOfException);

    this.rootCauses = rootCauses;
    this.exception = exception;
    this.rootCauseOfException = rootCauseOfException;
    this.cycles = cycles;
    this.isTransient = isTransient;
    this.isCatastrophic = isCatostrophic;
  }

  @Override
  public String toString() {
    return String.format("<ErrorInfo exception=%s rootCauses=%s cycles=%s>",
        exception, rootCauses, cycles);
  }

  /**
   * The root causes of a value that failed to build are its descendant values that failed to build.
   * If a value's descendants all built successfully, but it failed to, its root cause will be
   * itself. If a value depends on a cycle, but has no other errors, this method will return
   * the empty set.
   */
  public Iterable<SkyKey> getRootCauses() {
    return rootCauses;
  }

  /**
   * The exception thrown when building a value. May be null if value's only error is depending
   * on a cycle.
   *
   * <p>The exception is used for reporting and thus may ultimately be rethrown by the caller.
   * As well, during a --nokeep_going evaluation, if an error value is encountered from an earlier
   * --keep_going build, the exception to be thrown is taken from here.
   */
  @Nullable public Exception getException() {
    return exception;
  }

  public SkyKey getRootCauseOfException() {
    return rootCauseOfException;
  }

  /**
   * Any cycles found when building this value.
   *
   * <p>If there are a large number of cycles, only a limited number are returned here.
   *
   * <p>If this value has a child through which there are multiple paths to the same cycle, only one
   * path is returned here. However, if there are multiple paths to the same cycle, each of which
   * goes through a different child, each of them is returned here.
   */
  public Iterable<CycleInfo> getCycleInfo() {
    return cycles;
  }

  /**
   * Returns true iff the error is transitively transient, i.e. if retrying the same computation
   * could lead to a different result.
   */
  public boolean isTransient() {
    return isTransient;
  }

  /**
   * Returns true iff the error is catastrophic, i.e. it should halt even for a keepGoing update()
   * call.
   */
  public boolean isCatastrophic() {
    return isCatastrophic;
  }

}
