// 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.analysis.test;

import com.google.common.base.Joiner;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.build.lib.actions.Artifact;
import com.google.devtools.build.lib.actions.CommandLine;
import com.google.devtools.build.lib.actions.CommandLineExpansionException;
import com.google.devtools.build.lib.analysis.FilesToRunProvider;
import com.google.devtools.build.lib.analysis.RuleContext;
import com.google.devtools.build.lib.analysis.Runfiles;
import com.google.devtools.build.lib.analysis.RunfilesSupport;
import com.google.devtools.build.lib.analysis.TransitiveInfoCollection;
import com.google.devtools.build.lib.analysis.actions.FileWriteAction;
import com.google.devtools.build.lib.analysis.config.BuildConfiguration;
import com.google.devtools.build.lib.analysis.config.RunUnder;
import com.google.devtools.build.lib.analysis.configuredtargets.RuleConfiguredTarget.Mode;
import com.google.devtools.build.lib.packages.TargetUtils;
import com.google.devtools.build.lib.vfs.Path;
import javax.annotation.Nullable;

/**
 * Container for common test execution settings shared by all
 * all TestRunnerAction instances for the given test target.
 */
public final class TestTargetExecutionSettings {

  private final CommandLine testArguments;
  private final String testFilter;
  private final int totalShards;
  private final int totalRuns;
  private final RunUnder runUnder;
  private final Artifact runUnderExecutable;
  private final Artifact executable;
  private final boolean runfilesSymlinksCreated;
  @Nullable private final Path runfilesDir;
  private final Runfiles runfiles;
  private final Artifact runfilesInputManifest;
  private final Artifact instrumentedFileManifest;

  TestTargetExecutionSettings(
      RuleContext ruleContext,
      RunfilesSupport runfilesSupport,
      Artifact executable,
      Artifact instrumentedFileManifest,
      Artifact persistentTestRunnerFlagFile,
      int shards,
      int runs) {
    Preconditions.checkArgument(TargetUtils.isTestRule(ruleContext.getRule()));
    Preconditions.checkArgument(shards >= 0);
    BuildConfiguration config = ruleContext.getConfiguration();
    TestConfiguration testConfig = config.getFragment(TestConfiguration.class);

    CommandLine targetArgs = runfilesSupport.getArgs();
    if (persistentTestRunnerFlagFile != null) {
      // If an flag artifact exists for the persistent test runner, register an action that writes
      // the test arguments to the said artifact. When the test runner runs in a persistent worker,
      // the worker expects to find the test arguments in a special flag file.
      ImmutableList.Builder<String> testTargetArgs = new ImmutableList.Builder<>();
      try {
        testTargetArgs.addAll(targetArgs.arguments());
      } catch (CommandLineExpansionException e) {
        // Don't fail the build and ignore the runfiles arguments.
        ruleContext.ruleError("Could not expand test target arguments: " + e.getMessage());
      }
      testTargetArgs.addAll(testConfig.getTestArguments());
      ruleContext.registerAction(
          FileWriteAction.create(
              ruleContext.getActionOwner(),
              persistentTestRunnerFlagFile,
              /* fileContents= */ Joiner.on(System.lineSeparator()).join(testTargetArgs.build()),
              /* makeExecutable= */ false,
              /* allowCompression= */ FileWriteAction.Compression.DISALLOW));

      // When using the persistent test runner the test arguments are passed through --flagfile.
      testArguments =
          CommandLine.of(
              ImmutableList.of(
                  "--flagfile=" + persistentTestRunnerFlagFile.getRootRelativePathString()));
    } else {
      testArguments =
          CommandLine.concat(targetArgs, ImmutableList.copyOf(testConfig.getTestArguments()));
    }

    totalShards = shards;
    totalRuns = runs;
    runUnder = config.getRunUnder();
    runUnderExecutable = getRunUnderExecutable(ruleContext);

    this.testFilter = testConfig.getTestFilter();
    this.executable = executable;
    this.runfilesSymlinksCreated = runfilesSupport.isBuildRunfileLinks();
    this.runfilesDir = runfilesSupport.getRunfilesDirectory();
    this.runfiles = runfilesSupport.getRunfiles();
    this.runfilesInputManifest = runfilesSupport.getRunfilesInputManifest();
    this.instrumentedFileManifest = instrumentedFileManifest;
  }

  private static Artifact getRunUnderExecutable(RuleContext ruleContext) {
    TransitiveInfoCollection runUnderTarget = ruleContext
        .getPrerequisite(":run_under", Mode.DONT_CHECK);
    return runUnderTarget == null
        ? null
        : runUnderTarget.getProvider(FilesToRunProvider.class).getExecutable();
  }

  public Artifact getRunUnderExecutable() {
    return runUnderExecutable;
  }

  public CommandLine getArgs() {
    return testArguments;
  }

  public String getTestFilter() {
    return testFilter;
  }

  public int getTotalShards() {
    return totalShards;
  }

  public int getTotalRuns() {
    return totalRuns;
  }

  public RunUnder getRunUnder() {
    return runUnder;
  }

  public Artifact getExecutable() {
    return executable;
  }

  /** @return whether or not the runfiles symlinks were created */
  public boolean getRunfilesSymlinksCreated() {
    return runfilesSymlinksCreated;
  }

  /** @return the directory of the runfiles. */
  @Nullable
  public Path getRunfilesDir() {
    return runfilesDir;
  }

  /** @return the runfiles for the test */
  public Runfiles getRunfiles() {
    return runfiles;
  }

  /**
   * Returns the input runfiles manifest for this test.
   *
   * <p>This always returns the input manifest outside of the runfiles tree.
   *
   * @see com.google.devtools.build.lib.analysis.RunfilesSupport#getRunfilesInputManifest()
   */
  public Artifact getInputManifest() {
    return runfilesInputManifest;
  }

  /**
   * Returns instrumented file manifest or null if code coverage is not
   * collected.
   */
  public Artifact getInstrumentedFileManifest() {
    return instrumentedFileManifest;
  }

  public boolean needsShell(boolean executedOnWindows) {
    RunUnder r = getRunUnder();
    if (r == null) {
      return false;
    }
    String command = r.getCommand();
    if (command == null) {
      return false;
    }
    // --run_under commands that do not contain '/' are either shell built-ins or need to be
    // located on the PATH env, so we wrap them in a shell invocation. Note that we shell-tokenize
    // the --run_under parameter and getCommand only returns the first such token.
    return !command.contains("/") && (!executedOnWindows || !command.contains("\\"));
  }
}
