// Copyright 2014 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.standalone;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.analysis.actions.FileWriteActionContext;
import com.google.devtools.build.lib.analysis.actions.LocalTemplateExpansionStrategy;
import com.google.devtools.build.lib.analysis.actions.TemplateExpansionContext;
import com.google.devtools.build.lib.analysis.test.TestActionContext;
import com.google.devtools.build.lib.buildtool.BuildRequest;
import com.google.devtools.build.lib.dynamic.DynamicExecutionOptions;
import com.google.devtools.build.lib.exec.ExecutionOptions;
import com.google.devtools.build.lib.exec.FileWriteStrategy;
import com.google.devtools.build.lib.exec.ModuleActionContextRegistry;
import com.google.devtools.build.lib.exec.RunfilesTreeUpdater;
import com.google.devtools.build.lib.exec.SpawnRunner;
import com.google.devtools.build.lib.exec.SpawnStrategyRegistry;
import com.google.devtools.build.lib.exec.StandaloneTestStrategy;
import com.google.devtools.build.lib.exec.TestStrategy;
import com.google.devtools.build.lib.exec.local.LocalEnvProvider;
import com.google.devtools.build.lib.exec.local.LocalExecutionOptions;
import com.google.devtools.build.lib.exec.local.LocalSpawnRunner;
import com.google.devtools.build.lib.rules.cpp.CppIncludeExtractionContext;
import com.google.devtools.build.lib.rules.cpp.CppIncludeScanningContext;
import com.google.devtools.build.lib.rules.test.ExclusiveTestStrategy;
import com.google.devtools.build.lib.runtime.BlazeModule;
import com.google.devtools.build.lib.runtime.CommandEnvironment;
import com.google.devtools.build.lib.util.AbruptExitException;
import com.google.devtools.build.lib.util.ExitCode;
import com.google.devtools.build.lib.vfs.Path;

/**
 * StandaloneModule provides pluggable functionality for blaze.
 */
public class StandaloneModule extends BlazeModule {

  @Override
  public void beforeCommand(CommandEnvironment env) throws AbruptExitException {
    LocalExecutionOptions localOptions = env.getOptions().getOptions(LocalExecutionOptions.class);
    if (localOptions == null) {
      // This module doesn't make sense in non-build commands (which don't register these options).
      return;
    }

    DynamicExecutionOptions dynamicOptions =
        env.getOptions().getOptions(DynamicExecutionOptions.class);
    if (dynamicOptions != null) { // Guard against tests that don't pull this module in.
      if (localOptions.localLockfreeOutput && dynamicOptions.legacySpawnScheduler) {
        throw new AbruptExitException(
            "--experimental_local_lockfree_output requires --nolegacy_spawn_scheduler",
            ExitCode.COMMAND_LINE_ERROR);
      }
    }
  }

  @Override
  public void registerActionContexts(
      ModuleActionContextRegistry.Builder registryBuilder,
      CommandEnvironment env,
      BuildRequest buildRequest) {
    // TODO(ulfjack): Move this to another module.
    registryBuilder
        .register(CppIncludeExtractionContext.class, new DummyCppIncludeExtractionContext(env))
        .register(CppIncludeScanningContext.class, new DummyCppIncludeScanningContext());

    ExecutionOptions executionOptions = env.getOptions().getOptions(ExecutionOptions.class);
    Path testTmpRoot =
        TestStrategy.getTmpRoot(env.getWorkspace(), env.getExecRoot(), executionOptions);
    TestActionContext testStrategy =
        new StandaloneTestStrategy(
            executionOptions,
            env.getBlazeWorkspace().getBinTools(),
            testTmpRoot);

    registryBuilder.register(TestActionContext.class, testStrategy, "standalone");
    registryBuilder.register(
        TestActionContext.class, new ExclusiveTestStrategy(testStrategy), "exclusive");
    registryBuilder.register(FileWriteActionContext.class, new FileWriteStrategy(), "local");
    registryBuilder.register(
        TemplateExpansionContext.class, new LocalTemplateExpansionStrategy(), "local");
  }

  @Override
  public void registerSpawnStrategies(
      SpawnStrategyRegistry.Builder registryBuilder, CommandEnvironment env) {
    SpawnRunner localSpawnRunner =
        new LocalSpawnRunner(
            env.getExecRoot(),
            env.getOptions().getOptions(LocalExecutionOptions.class),
            env.getLocalResourceManager(),
            LocalEnvProvider.forCurrentOs(env.getClientEnv()),
            env.getBlazeWorkspace().getBinTools(),
            // TODO(buchgr): Replace singleton by a command-scoped RunfilesTreeUpdater
            RunfilesTreeUpdater.INSTANCE);

    // Order of strategies passed to builder is significant - when there are many strategies that
    // could potentially be used and a spawnActionContext doesn't specify which one it wants, the
    // last one from strategies list will be used
    registryBuilder.registerStrategy(
        new StandaloneSpawnStrategy(env.getExecRoot(), localSpawnRunner), "standalone", "local");

    // This makes the "standalone" strategy the default Spawn strategy, unless it is overridden by a
    // later BlazeModule.
    registryBuilder.setDefaultStrategies(ImmutableList.of("standalone"));
  }
}
