// Copyright 2015 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.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.google.devtools.build.lib.util.GroupedList;
import java.util.Collections;
import java.util.Map;
import javax.annotation.Nullable;

/**
 * Basic implementation of {@link SkyFunction.Environment} in which all convenience methods delegate
 * to a single abstract method.
 */
@VisibleForTesting
public abstract class AbstractSkyFunctionEnvironment implements SkyFunction.Environment {
  protected boolean valuesMissing = false;
  // Hack for the common case that there are no errors in the retrieved values. In that case, we
  // don't have to filter out any impermissible exceptions. Hack because we communicate this in an
  // out-of-band way from #getValueOrUntypedExceptions. It's out-of-band because we don't want to
  // incur the garbage overhead of returning a more complex data structure from
  // #getValueOrUntypedExceptions.
  protected boolean errorMightHaveBeenFound = false;
  @Nullable private final GroupedList<SkyKey> temporaryDirectDeps;

  public AbstractSkyFunctionEnvironment(@Nullable GroupedList<SkyKey> temporaryDirectDeps) {
    this.temporaryDirectDeps = temporaryDirectDeps;
  }

  public AbstractSkyFunctionEnvironment() {
    this(null);
  }

  @Override
  public GroupedList<SkyKey> getTemporaryDirectDeps() {
    return temporaryDirectDeps;
  }

  /** Implementations should set {@link #valuesMissing} as necessary. */
  protected abstract Map<SkyKey, ValueOrUntypedException> getValueOrUntypedExceptions(
      Iterable<? extends SkyKey> depKeys) throws InterruptedException;

  @Override
  @Nullable
  public SkyValue getValue(SkyKey depKey) throws InterruptedException {
    return getValues(ImmutableSet.of(depKey)).get(depKey);
  }

  @Override
  @Nullable
  public <E extends Exception> SkyValue getValueOrThrow(SkyKey depKey, Class<E> exceptionClass)
      throws E, InterruptedException {
    return getValuesOrThrow(ImmutableSet.of(depKey), exceptionClass).get(depKey).get();
  }

  @Override
  @Nullable
  public <E1 extends Exception, E2 extends Exception> SkyValue getValueOrThrow(
      SkyKey depKey, Class<E1> exceptionClass1, Class<E2> exceptionClass2)
      throws E1, E2, InterruptedException {
    return getValuesOrThrow(ImmutableSet.of(depKey), exceptionClass1, exceptionClass2)
        .get(depKey)
        .get();
  }

  @Override
  @Nullable
  public <E1 extends Exception, E2 extends Exception, E3 extends Exception>
      SkyValue getValueOrThrow(
          SkyKey depKey,
          Class<E1> exceptionClass1,
          Class<E2> exceptionClass2,
          Class<E3> exceptionClass3)
          throws E1, E2, E3, InterruptedException {
    return getValuesOrThrow(
            ImmutableSet.of(depKey), exceptionClass1, exceptionClass2, exceptionClass3)
        .get(depKey)
        .get();
  }

  @Override
  public <E1 extends Exception, E2 extends Exception, E3 extends Exception, E4 extends Exception>
      SkyValue getValueOrThrow(
          SkyKey depKey,
          Class<E1> exceptionClass1,
          Class<E2> exceptionClass2,
          Class<E3> exceptionClass3,
          Class<E4> exceptionClass4)
          throws E1, E2, E3, E4, InterruptedException {
    return getValuesOrThrow(
            ImmutableSet.of(depKey),
            exceptionClass1,
            exceptionClass2,
            exceptionClass3,
            exceptionClass4)
        .get(depKey)
        .get();
  }

  @Override
  public <
          E1 extends Exception,
          E2 extends Exception,
          E3 extends Exception,
          E4 extends Exception,
          E5 extends Exception>
      SkyValue getValueOrThrow(
          SkyKey depKey,
          Class<E1> exceptionClass1,
          Class<E2> exceptionClass2,
          Class<E3> exceptionClass3,
          Class<E4> exceptionClass4,
          Class<E5> exceptionClass5)
          throws E1, E2, E3, E4, E5, InterruptedException {
    return getValuesOrThrow(
            ImmutableSet.of(depKey),
            exceptionClass1,
            exceptionClass2,
            exceptionClass3,
            exceptionClass4,
            exceptionClass5)
        .get(depKey)
        .get();
  }

  @Override
  public Map<SkyKey, SkyValue> getValues(Iterable<? extends SkyKey> depKeys)
      throws InterruptedException {
    Map<SkyKey, ValueOrUntypedException> valuesOrExceptions = getValueOrUntypedExceptions(depKeys);
    checkValuesMissingBecauseOfFilteredError(valuesOrExceptions, null, null, null, null, null);
    return Collections.unmodifiableMap(
        Maps.transformValues(valuesOrExceptions, ValueOrUntypedException::getValue));
  }

  @Override
  public <E extends Exception> Map<SkyKey, ValueOrException<E>> getValuesOrThrow(
      Iterable<? extends SkyKey> depKeys, Class<E> exceptionClass) throws InterruptedException {
    SkyFunctionException.validateExceptionType(exceptionClass);
    Map<SkyKey, ValueOrUntypedException> valuesOrExceptions = getValueOrUntypedExceptions(depKeys);
    checkValuesMissingBecauseOfFilteredError(
        valuesOrExceptions, exceptionClass, null, null, null, null);
    return Collections.unmodifiableMap(
        Maps.transformValues(
            valuesOrExceptions, voe -> ValueOrException.fromUntypedException(voe, exceptionClass)));
  }

  @Override
  public <E1 extends Exception, E2 extends Exception>
      Map<SkyKey, ValueOrException2<E1, E2>> getValuesOrThrow(
          Iterable<? extends SkyKey> depKeys, Class<E1> exceptionClass1, Class<E2> exceptionClass2)
              throws InterruptedException {
    SkyFunctionException.validateExceptionType(exceptionClass1);
    SkyFunctionException.validateExceptionType(exceptionClass2);
    Map<SkyKey, ValueOrUntypedException> valuesOrExceptions = getValueOrUntypedExceptions(depKeys);
    checkValuesMissingBecauseOfFilteredError(
        valuesOrExceptions, exceptionClass1, exceptionClass2, null, null, null);
    return Collections.unmodifiableMap(
        Maps.transformValues(
            valuesOrExceptions,
            voe -> ValueOrException2.fromUntypedException(voe, exceptionClass1, exceptionClass2)));
  }

  @Override
  public <E1 extends Exception, E2 extends Exception, E3 extends Exception>
      Map<SkyKey, ValueOrException3<E1, E2, E3>> getValuesOrThrow(
          Iterable<? extends SkyKey> depKeys,
          Class<E1> exceptionClass1,
          Class<E2> exceptionClass2,
          Class<E3> exceptionClass3)
              throws InterruptedException {
    SkyFunctionException.validateExceptionType(exceptionClass1);
    SkyFunctionException.validateExceptionType(exceptionClass2);
    SkyFunctionException.validateExceptionType(exceptionClass3);
    Map<SkyKey, ValueOrUntypedException> valuesOrExceptions = getValueOrUntypedExceptions(depKeys);
    checkValuesMissingBecauseOfFilteredError(
        valuesOrExceptions, exceptionClass1, exceptionClass2, exceptionClass3, null, null);
    return Collections.unmodifiableMap(
        Maps.transformValues(
            valuesOrExceptions,
            voe ->
                ValueOrException3.fromUntypedException(
                    voe, exceptionClass1, exceptionClass2, exceptionClass3)));
  }

  @Override
  public <E1 extends Exception, E2 extends Exception, E3 extends Exception, E4 extends Exception>
      Map<SkyKey, ValueOrException4<E1, E2, E3, E4>> getValuesOrThrow(
          Iterable<? extends SkyKey> depKeys,
          Class<E1> exceptionClass1,
          Class<E2> exceptionClass2,
          Class<E3> exceptionClass3,
          Class<E4> exceptionClass4)
           throws InterruptedException {
    SkyFunctionException.validateExceptionType(exceptionClass1);
    SkyFunctionException.validateExceptionType(exceptionClass2);
    SkyFunctionException.validateExceptionType(exceptionClass3);
    SkyFunctionException.validateExceptionType(exceptionClass4);
    Map<SkyKey, ValueOrUntypedException> valuesOrExceptions = getValueOrUntypedExceptions(depKeys);
    checkValuesMissingBecauseOfFilteredError(
        valuesOrExceptions,
        exceptionClass1,
        exceptionClass2,
        exceptionClass3,
        exceptionClass4,
        null);
    return Collections.unmodifiableMap(
        Maps.transformValues(
            valuesOrExceptions,
            voe ->
                ValueOrException4.fromUntypedException(
                    voe, exceptionClass1, exceptionClass2, exceptionClass3, exceptionClass4)));
  }

  @Override
  public <
          E1 extends Exception,
          E2 extends Exception,
          E3 extends Exception,
          E4 extends Exception,
          E5 extends Exception>
      Map<SkyKey, ValueOrException5<E1, E2, E3, E4, E5>> getValuesOrThrow(
          Iterable<? extends SkyKey> depKeys,
          Class<E1> exceptionClass1,
          Class<E2> exceptionClass2,
          Class<E3> exceptionClass3,
          Class<E4> exceptionClass4,
          Class<E5> exceptionClass5)
              throws InterruptedException {
    SkyFunctionException.validateExceptionType(exceptionClass1);
    SkyFunctionException.validateExceptionType(exceptionClass2);
    SkyFunctionException.validateExceptionType(exceptionClass3);
    SkyFunctionException.validateExceptionType(exceptionClass4);
    SkyFunctionException.validateExceptionType(exceptionClass5);
    Map<SkyKey, ValueOrUntypedException> valuesOrExceptions = getValueOrUntypedExceptions(depKeys);
    checkValuesMissingBecauseOfFilteredError(
        valuesOrExceptions,
        exceptionClass1,
        exceptionClass2,
        exceptionClass3,
        exceptionClass4,
        exceptionClass5);
    return Collections.unmodifiableMap(
        Maps.transformValues(
            valuesOrExceptions,
            voe ->
                ValueOrException5.fromUntypedException(
                    voe,
                    exceptionClass1,
                    exceptionClass2,
                    exceptionClass3,
                    exceptionClass4,
                    exceptionClass5)));
  }

  private <
          E1 extends Exception,
          E2 extends Exception,
          E3 extends Exception,
          E4 extends Exception,
          E5 extends Exception>
      void checkValuesMissingBecauseOfFilteredError(
          Map<SkyKey, ValueOrUntypedException> voes,
          @Nullable Class<E1> exceptionClass1,
          @Nullable Class<E2> exceptionClass2,
          @Nullable Class<E3> exceptionClass3,
          @Nullable Class<E4> exceptionClass4,
          @Nullable Class<E5> exceptionClass5) {
    if (!errorMightHaveBeenFound) {
      // Short-circuit in the common case of no errors.
      return;
    }
    for (ValueOrUntypedException voe : voes.values()) {
      SkyValue value = voe.getValue();
      if (value == null) {
        Exception e = voe.getException();
        if (e == null
            || ((exceptionClass1 == null || !exceptionClass1.isInstance(e))
                && (exceptionClass2 == null || !exceptionClass2.isInstance(e))
                && (exceptionClass3 == null || !exceptionClass3.isInstance(e))
                && (exceptionClass4 == null || !exceptionClass4.isInstance(e))
                && (exceptionClass5 == null || !exceptionClass5.isInstance(e)))) {
          valuesMissing = true;
          return;
        }
      }
    }
  }

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