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

import java.util.Iterator;
import java.util.NoSuchElementException;
import javax.annotation.Nullable;

/**
 * An iterable-like result of getting Skyframe dependencies via {@link
 * SkyFunction.Environment#getOrderedValuesAndExceptions}. Callers can use the {@link #next} and
 * {@link #nextOrThrow} methods to obtain successive elements.
 *
 * <p>Can only be iterated through once: if an iterable of size k was passed to {@link
 * SkyFunction.Environment#getOrderedValuesAndExceptions}, then the returned {@link
 * SkyframeIterableResult} can have {@link #next} and {@link #nextOrThrow} called a total of k
 * times.
 *
 * <p>Note that a {@link SkyFunction} cannot guarantee that {@link
 * SkyFunction.Environment#valuesMissing} will be true upon receipt of a {@code
 * SkyframeIterableResult}. The elements must be iterated over. If {@link #next} or {@link
 * #nextOrThrow} returns {@code null}, only then will {@link SkyFunction.Environment#valuesMissing}
 * be guaranteed to return true.
 */
public final class SkyframeIterableResult {
  private final Iterator<ValueOrUntypedException> valuesOrExceptions;
  private final Runnable valuesMissingCallback;

  SkyframeIterableResult(
      Runnable valuesMissingCallback, Iterator<ValueOrUntypedException> valuesOrExceptions) {
    this.valuesMissingCallback = checkNotNull(valuesMissingCallback);
    this.valuesOrExceptions = checkNotNull(valuesOrExceptions);
  }

  /**
   * Returns true if {@link SkyframeIterableResult} has more elements. In other words, returns true
   * if {@link #next} or {@link #nextOrThrow} would return an element rather than throwing a {@link
   * NoSuchElementException}.
   */
  public boolean hasNext() {
    return valuesOrExceptions.hasNext();
  }

  /**
   * Returns the next direct dependency in {@link SkyframeIterableResult}. If the dependency is not
   * in the set of already evaluated direct dependencies, returns {@code null}. Also returns {@code
   * null} if the dependency has already been evaluated and found to be in error. In either of these
   * cases, {@link SkyFunction.Environment#valuesMissing} will subsequently return true.
   */
  public SkyValue next() {
    return nextOrThrow(null, null, null);
  }

  /**
   * Returns the next direct dependency in {@link SkyframeIterableResult}. If the dependency is not
   * in the set of already evaluated direct dependencies, returns {@code null}. If the dependency
   * has already been evaluated and found to be in error, throws the exception coming from the
   * error, so long as the exception is of one of the specified types. SkyFunction implementations
   * may use this method to catch and rethrow a more informative exception or to continue
   * evaluation. The caller must specify the exception type(s) that might be thrown using the {@code
   * exceptionClass} argument(s). If the dependency's exception is not an instance of {@code
   * exceptionClass}, {@code null} is returned. In this case, {@link
   * SkyFunction.Environment#valuesMissing} will subsequently return true.
   *
   * <p>The exception class given cannot be a supertype or a subtype of {@link RuntimeException}, or
   * a subtype of {@link InterruptedException}. See {@link
   * SkyFunctionException#validateExceptionType} for details.
   */
  public <E1 extends Exception> SkyValue nextOrThrow(Class<E1> exceptionClass) throws E1 {
    return nextOrThrow(exceptionClass, null, null, null);
  }

  public <E1 extends Exception, E2 extends Exception> SkyValue nextOrThrow(
      Class<E1> exceptionClass1, Class<E2> exceptionClass2) throws E1, E2 {
    return nextOrThrow(exceptionClass1, exceptionClass2, null, null);
  }

  public <E1 extends Exception, E2 extends Exception, E3 extends Exception> SkyValue nextOrThrow(
      Class<E1> exceptionClass1, Class<E2> exceptionClass2, Class<E3> exceptionClass3)
      throws E1, E2, E3 {
    return nextOrThrow(exceptionClass1, exceptionClass2, exceptionClass3, null);
  }

  public <E1 extends Exception, E2 extends Exception, E3 extends Exception, E4 extends Exception>
      SkyValue nextOrThrow(
          @Nullable Class<E1> exceptionClass1,
          @Nullable Class<E2> exceptionClass2,
          @Nullable Class<E3> exceptionClass3,
          @Nullable Class<E4> exceptionClass4)
          throws E1, E2, E3, E4 {
    ValueOrUntypedException voe = valuesOrExceptions.next();
    SkyValue value = voe.getValue();
    if (value != null) {
      return value;
    }
    Exception e = voe.getException();
    if (e != null) {
      if (exceptionClass1 != null && exceptionClass1.isInstance(e)) {
        throw exceptionClass1.cast(e);
      }
      if (exceptionClass2 != null && exceptionClass2.isInstance(e)) {
        throw exceptionClass2.cast(e);
      }
      if (exceptionClass3 != null && exceptionClass3.isInstance(e)) {
        throw exceptionClass3.cast(e);
      }
      if (exceptionClass4 != null && exceptionClass4.isInstance(e)) {
        throw exceptionClass4.cast(e);
      }
    }
    valuesMissingCallback.run();
    return null;
  }
}
