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

import static com.google.common.util.concurrent.MoreExecutors.directExecutor;
import static com.google.common.util.concurrent.Uninterruptibles.getUninterruptibly;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.devtools.build.lib.bugreport.BugReporter;
import com.google.devtools.build.lib.skyframe.serialization.FingerprintValueStore.MissingFingerprintValueException;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;

/** Helpers for serialization futures. */
@VisibleForTesting // package-private
public final class FutureHelpers {

  /**
   * Waits for {@code future} and returns the result.
   *
   * <p>Handles exceptions by converting them into {@link SerializationException}.
   */
  @VisibleForTesting // package-private
  @CanIgnoreReturnValue // may be called for side effects
  public static <T> T waitForSerializationFuture(ListenableFuture<T> future)
      throws SerializationException {
    try {
      // TODO: b/297857068 - revisit whether this should handle to interrupts. As of 02/09/24,
      // serialization doesn't handle interrupts so introducing them here could lead to unforseen
      // problems.
      return getUninterruptibly(future);
    } catch (ExecutionException e) {
      throw asSerializationException(e.getCause());
    }
  }

  /**
   * Gets the done value of {@code future}.
   *
   * <p>Handles exceptions by converting them into {@link SerializationException}.
   */
  static <T> T getDoneSerializationFuture(ListenableFuture<T> future)
      throws SerializationException {
    try {
      return Futures.getDone(future);
    } catch (ExecutionException e) {
      throw asSerializationException(e.getCause());
    }
  }

  /**
   * Waits for {@code future} and returns the result.
   *
   * <p>Handles exceptions by converting them into {@link SerializationException}. The {@link
   * SerializationException} may have a {@link MissingFingerprintValueException} cause.
   *
   * <p>The {@link MissingFingerprintValueException} needs special case handling anywhere this
   * method is used. Outside of test code, this is only possible for via {@link
   * SharedValueDeserializationContext#deserializeWithSharedValues}, which explicitly handles it.
   */
  @CanIgnoreReturnValue // may be called for side effects
  static <T> T waitForDeserializationFuture(ListenableFuture<T> future)
      throws SerializationException {
    try {
      // TODO: b/297857068 - revisit whether this should handle to interrupts. As of 02/09/24,
      // serialization doesn't handle interrupts so introducing them here could lead to unforseen
      // problems.
      return getUninterruptibly(future);
    } catch (ExecutionException e) {
      throw asDeserializationException(e.getCause());
    }
  }

  /**
   * Gets the done value of {@code future}.
   *
   * <p>May throw an {@link IllegalStateException} if the future is not done. See {@link
   * #waitForDeserializationFuture} for a description the {@link SerializationException}.
   */
  static <T> T getDoneDeserializationFuture(ListenableFuture<T> future)
      throws SerializationException {
    try {
      return Futures.getDone(future);
    } catch (ExecutionException e) {
      throw asDeserializationException(e.getCause());
    }
  }

  /**
   * Reports any errors that occur on {@code combiner}.
   *
   * <p>Used when a future value is going to be discarded, but it would be inappropriate to ignore
   * possible errors.
   */
  static void reportAnyFailures(Futures.FutureCombiner<?> combiner) {
    Futures.addCallback(
        combiner.call(() -> null, directExecutor()),
        new FutureCallback<Void>() {
          @Override
          public void onSuccess(Void unused) {}

          @Override
          public void onFailure(Throwable t) {
            BugReporter.defaultInstance().sendBugReport(t);
          }
        },
        directExecutor());
  }

  /** Combines a list of {@code Void} futures into a single future. */
  static ListenableFuture<Void> aggregateStatusFutures(List<ListenableFuture<Void>> futures) {
    if (futures.size() == 1) {
      return futures.get(0);
    }
    return Futures.whenAllSucceed(futures).call(() -> null, directExecutor());
  }

  private static SerializationException asDeserializationException(Throwable cause) {
    if (cause instanceof MissingFingerprintValueException) {
      return new SerializationException(cause);
    }
    return asSerializationException(cause);
  }

  private static SerializationException asSerializationException(Throwable cause) {
    if (cause instanceof SerializationException) {
      return new SerializationException(cause);
    }
    if (cause instanceof IOException) {
      return new SerializationException("serialization I/O error", cause);
    }
    return new SerializationException("unexpected serialization error", cause);
  }

  private FutureHelpers() {}
}
