// Copyright 2019 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.actions;

import com.google.common.collect.ImmutableList;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.List;

/**
 * A representation of a (potentially) multi-step spawn execution, which can return multiple
 * results. This covers cases like remote/local fallback as well as tree artifact packing/unpacking,
 * which both require multiple attempts at running a spawn, and therefore can have multiple results.
 *
 * <p>This is intentionally similar to {@link ActionContinuationOrResult}, which will often wrap one
 * of these.
 *
 * <p>Any client of this class <b>should</b> first call {@link #isDone} before calling any of the
 * other methods. If {@link #isDone} returns true, then {@link #execute} must return this, and
 * {@link #get} must return the result. Use {@link #immediate} to construct such an instance. {@link
 * #getFuture} should return a completed future (see {@link Futures#immediateFuture}).
 *
 * <p>Otherwise, {@link #getFuture} must return a non-null value, {@link #execute} must not throw
 * {@link IllegalStateException}, and {@link #get} must throw {@link IllegalStateException}. Note
 * that calling {@link #execute} without waiting for the future to complete will likely block.
 *
 * <p>That is, it is always safe to call {@link #isDone}, {@link #getFuture}, and {@link #execute},
 * but it is only safe to call {@link #get} if the continuation is done.
 */
public abstract class SpawnContinuation {
  public static SpawnContinuation immediate(SpawnResult... spawnResults) {
    return new Finished(ImmutableList.copyOf(spawnResults));
  }

  public static SpawnContinuation immediate(List<SpawnResult> spawnResults) {
    return new Finished(ImmutableList.copyOf(spawnResults));
  }

  public static SpawnContinuation failedWithExecException(ExecException e) {
    return new FailedWithExecException(e);
  }

  /**
   * Runs the state machine represented by the given continuation to completion, blocking as
   * necessary until all asynchronous computations finish, and the final continuation is done. Then
   * returns the list of spawn results (calling {@link SpawnContinuation#get}).
   *
   * <p>This method provides backwards compatibility for the cases where a method that's defined as
   * blocking obtains a continuation and needs the result before it can return. Over time, this
   * method should become less common as more actions are rewritten to support async execution.
   */
  public static List<SpawnResult> completeBlocking(SpawnContinuation continuation)
      throws ExecException, InterruptedException {
    while (!continuation.isDone()) {
      continuation = continuation.execute();
    }
    return continuation.get();
  }

  public boolean isDone() {
    return false;
  }

  public abstract ListenableFuture<?> getFuture();

  public abstract SpawnContinuation execute() throws ExecException, InterruptedException;

  public List<SpawnResult> get() {
    throw new IllegalStateException();
  }

  private static final class Finished extends SpawnContinuation {
    private final List<SpawnResult> spawnResults;

    Finished(List<SpawnResult> spawnResults) {
      this.spawnResults = spawnResults;
    }

    public boolean isDone() {
      return true;
    }

    @Override
    public ListenableFuture<?> getFuture() {
      return Futures.immediateFuture(null);
    }

    @Override
    public SpawnContinuation execute() {
      return this;
    }

    public List<SpawnResult> get() {
      return spawnResults;
    }
  }

  private static final class FailedWithExecException extends SpawnContinuation {
    private final ExecException e;

    FailedWithExecException(ExecException e) {
      this.e = e;
    }

    @Override
    public ListenableFuture<?> getFuture() {
      // This call does not allocate memory because immediateFuture returns a singleton for null.
      return Futures.immediateFuture(null);
    }

    @Override
    public SpawnContinuation execute() throws ExecException {
      throw e;
    }
  }
}
