// Copyright 2016 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.remote;

import static com.google.common.base.Preconditions.checkNotNull;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.ActionContext;
import com.google.devtools.build.lib.actions.ExecutionStrategy;
import com.google.devtools.build.lib.actions.ExecutorInitException;
import com.google.devtools.build.lib.exec.AbstractSpawnStrategy;
import com.google.devtools.build.lib.exec.ActionContextProvider;
import com.google.devtools.build.lib.exec.ExecutionOptions;
import com.google.devtools.build.lib.exec.SpawnRunner;
import com.google.devtools.build.lib.remote.util.DigestUtil;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
import com.google.devtools.build.lib.util.ExitCode;
import com.google.devtools.build.lib.vfs.Path;
import java.util.Arrays;
import java.util.Collections;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;

/**
 * Provide a remote execution context.
 */
final class RemoteActionContextProvider extends ActionContextProvider {
  private final CommandEnvironment env;
  private final AbstractRemoteActionCache cache;
  @Nullable private final GrpcRemoteExecutor executor;
  private final RemoteRetrier retrier;
  private final DigestUtil digestUtil;
  @Nullable private final Path logDir;
  private final AtomicReference<SpawnRunner> fallbackRunner = new AtomicReference<>();

  private RemoteActionContextProvider(
      CommandEnvironment env,
      AbstractRemoteActionCache cache,
      @Nullable GrpcRemoteExecutor executor,
      RemoteRetrier retrier,
      DigestUtil digestUtil,
      @Nullable Path logDir) {
    this.env = Preconditions.checkNotNull(env, "env");
    this.cache = Preconditions.checkNotNull(cache, "cache");
    this.executor = executor;
    this.retrier = retrier;
    this.digestUtil = digestUtil;
    this.logDir = logDir;
  }

  public static RemoteActionContextProvider createForRemoteCaching(
      CommandEnvironment env,
      AbstractRemoteActionCache cache,
      RemoteRetrier retrier,
      DigestUtil digestUtil) {
    return new RemoteActionContextProvider(
        env, cache, /*executor=*/ null, retrier, digestUtil, /*logDir=*/ null);
  }

  public static RemoteActionContextProvider createForRemoteExecution(
      CommandEnvironment env,
      GrpcRemoteCache cache,
      GrpcRemoteExecutor executor,
      RemoteRetrier retrier,
      DigestUtil digestUtil,
      Path logDir) {
    return new RemoteActionContextProvider(env, cache, executor, retrier, digestUtil, logDir);
  }

  @Override
  public Iterable<? extends ActionContext> getActionContexts() {
    ExecutionOptions executionOptions =
        checkNotNull(env.getOptions().getOptions(ExecutionOptions.class));
    RemoteOptions remoteOptions = checkNotNull(env.getOptions().getOptions(RemoteOptions.class));
    String buildRequestId = env.getBuildRequestId();
    String commandId = env.getCommandId().toString();

    if (executor == null) {
      RemoteSpawnCache spawnCache =
          new RemoteSpawnCache(
              env.getExecRoot(),
              remoteOptions,
              cache,
              buildRequestId,
              commandId,
              env.getReporter(),
              digestUtil);
      return ImmutableList.of(spawnCache);
    } else {
      RemoteSpawnRunner spawnRunner =
          new RemoteSpawnRunner(
              env.getExecRoot(),
              remoteOptions,
              env.getOptions().getOptions(ExecutionOptions.class),
              fallbackRunner,
              executionOptions.verboseFailures,
              env.getReporter(),
              buildRequestId,
              commandId,
              (GrpcRemoteCache) cache,
              executor,
              retrier,
              digestUtil,
              logDir);
      return ImmutableList.of(new RemoteSpawnStrategy(env.getExecRoot(), spawnRunner));
    }
  }

  @Override
  public void executorCreated(Iterable<ActionContext> usedContexts) throws ExecutorInitException {
    SortedSet<String> validStrategies = new TreeSet<>();
    fallbackRunner.set(null);

    RemoteOptions remoteOptions = env.getOptions().getOptions(RemoteOptions.class);
    String strategyName = remoteOptions.remoteLocalFallbackStrategy;

    for (ActionContext context : usedContexts) {
      if (context instanceof RemoteSpawnStrategy && cache == null) {
        throw new ExecutorInitException(
            "--remote_cache or --remote_executor should be initialized when using "
                + "--spawn_strategy=remote",
            ExitCode.COMMAND_LINE_ERROR);
      }
      if (context instanceof AbstractSpawnStrategy) {
        ExecutionStrategy annotation = context.getClass().getAnnotation(ExecutionStrategy.class);
        if (annotation != null) {
          Collections.addAll(validStrategies, annotation.name());
          if (!strategyName.equals("remote")
              && Arrays.asList(annotation.name()).contains(strategyName)) {
            AbstractSpawnStrategy spawnStrategy = (AbstractSpawnStrategy) context;
            SpawnRunner spawnRunner = Preconditions.checkNotNull(spawnStrategy.getSpawnRunner());
            fallbackRunner.set(spawnRunner);
          }
        }
      }
    }

    if (fallbackRunner.get() == null) {
      validStrategies.remove("remote");
      throw new ExecutorInitException(
          String.format(
              "'%s' is an invalid value for --remote_local_fallback_strategy. Valid values are: %s",
              strategyName, validStrategies),
          ExitCode.COMMAND_LINE_ERROR);
    }
  }

  @Override
  public void executionPhaseEnding() {
    if (cache != null) {
      cache.close();
    }
    if (executor != null) {
      executor.close();
    }
  }
}
