// 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.devtools.build.lib.util.Preconditions;

import javax.annotation.Nullable;

/**
 * Base class of exceptions thrown by {@link SkyFunction#compute} on failure.
 *
 * SkyFunctions should declare a subclass {@code C} of {@link SkyFunctionException} whose
 * constructors forward fine-grained exception types (e.g. {@code IOException}) to
 * {@link SkyFunctionException}'s constructor, and they should also declare
 * {@link SkyFunction#compute} to throw {@code C}. This way the type system checks that no
 * unexpected exceptions are thrown by the {@link SkyFunction}.
 *
 * <p>We took this approach over using a generic exception class since Java disallows it because of
 * type erasure
 * (see http://docs.oracle.com/javase/tutorial/java/generics/restrictions.html#cannotCatch).
 *
 * <p> Note that there are restrictions on what Exception types are allowed to be wrapped in this
 * manner. See {@link SkyFunctionException#validateExceptionType}.
 *
 * <p>Failures are explicitly either transient or persistent. The transience of the failure from
 * {@link SkyFunction#compute} should be influenced only by the computations done, and not by the
 * transience of the failures from computations requested via
 * {@link SkyFunction.Environment#getValueOrThrow}.
 */
public abstract class SkyFunctionException extends Exception {

  /** The transience of the error. */
  public enum Transience {
    /**
     * An error that may or may not occur again if the computation were re-run. If a computation
     * results in a transient error and is needed on a subsequent MemoizingEvaluator#evaluate call,
     * it will be re-executed.
     */
    TRANSIENT,

    /**
     * An error that is completely deterministic and persistent in terms of the computation's
     * inputs. Persistent errors may be cached.
     */
    PERSISTENT;
  }

  private final Transience transience;
  @Nullable
  private final SkyKey rootCause;

  public SkyFunctionException(Exception cause, Transience transience) {
    this(cause, transience, null);
  }

  /** Used to rethrow a child error that the parent cannot handle. */
  public SkyFunctionException(Exception cause, SkyKey childKey) {
    this(cause, Transience.PERSISTENT, childKey);
  }

  private SkyFunctionException(Exception cause, Transience transience, SkyKey rootCause) {
    super(Preconditions.checkNotNull(cause));
    SkyFunctionException.validateExceptionType(cause.getClass());
    this.transience = transience;
    this.rootCause = rootCause;
  }

  @Nullable
  final SkyKey getRootCauseSkyKey() {
    return rootCause;
  }

  public final boolean isTransient() {
    return transience == Transience.TRANSIENT;
  }

  /**
   * Catastrophic failures halt the build even when in keepGoing mode.
   */
  public boolean isCatastrophic() {
    return false;
  }

  @Override
  public synchronized Exception getCause() {
    return (Exception) super.getCause();
  }

  static <E extends Exception> void validateExceptionType(Class<E> exceptionClass) {
    if (exceptionClass.equals(ValueOrExceptionUtils.BottomException.class)) {
      return;
    }

    if (exceptionClass.isAssignableFrom(RuntimeException.class)) {
      throw new IllegalStateException(exceptionClass.getSimpleName() + " is a supertype of "
          + "RuntimeException. Don't do this since then you would potentially swallow all "
          + "RuntimeExceptions, even those from Skyframe");
    }
    if (RuntimeException.class.isAssignableFrom(exceptionClass)) {
      throw new IllegalStateException(exceptionClass.getSimpleName() + " is a subtype of "
          + "RuntimeException. You should rewrite your code to use checked exceptions.");
    }
    if (InterruptedException.class.isAssignableFrom(exceptionClass)) {
      throw new IllegalStateException(exceptionClass.getSimpleName() + " is a subtype of "
          + "InterruptedException. Don't do this; Skyframe handles interrupts separately from the "
          + "general SkyFunctionException mechanism.");
    }
  }

  /** A {@link SkyFunctionException} with a definite root cause. */
  public static class ReifiedSkyFunctionException extends SkyFunctionException {
    private final boolean isCatastrophic;

    public ReifiedSkyFunctionException(SkyFunctionException e, SkyKey key) {
      super(e.getCause(), e.transience, Preconditions.checkNotNull(e.getRootCauseSkyKey() == null
          ? key : e.getRootCauseSkyKey()));
      this.isCatastrophic = e.isCatastrophic();
    }

    @Override
    public boolean isCatastrophic() {
      return isCatastrophic;
    }
  }
}
