// Copyright 2018 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.blackbox.framework;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.devtools.build.lib.blackbox.framework.ProcessRunner.ProcessRunnerException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * Class for running Bazel process in the working directory of the blackbox test.
 *
 * <p>Provides customization methods for timeout, environment variables, etc., which modify the
 * current instance of <code>BuilderRunner</code>, and also return it for chain calls.
 *
 * <p>The instance keeps only parameters for the Bazel invocations, like timeout or environment
 * variables values, but not the data related to the actual Bazel invocations. That is why the same
 * instance can be used to invoke several commands.
 */
public final class BuilderRunner {
  private static final long DEFAULT_TIMEOUT_MILLIS = TimeUnit.SECONDS.toMillis(30);

  private final Path workDir;
  private final Path binaryPath;
  private final Map<String, String> env;
  private final ExecutorService executorService;
  private long timeoutMillis;
  private boolean useDefaultRc = true;

  /**
   * Creates the BuilderRunner
   *
   * @param workDir working directory of the test
   * @param binaryPath {@link Path} to the Bazel executable
   * @param defaultTimeoutMillis default timeout in milliseconds to use if the user has not
   *     specified timeout for Bazel command invocation
   * @param env environment variables to be passed to Bazel process (part, common for all Bazel
   *     invocations)
   * @param executorService {@link ExecutorService} to be used by the {@link ProcessRunner}, which
   *     actually invokes the Bzel command
   */
  BuilderRunner(
      Path workDir,
      Path binaryPath,
      long defaultTimeoutMillis,
      Map<String, String> env,
      ExecutorService executorService) {
    Preconditions.checkNotNull(workDir);
    Preconditions.checkNotNull(binaryPath);
    Preconditions.checkNotNull(env);
    Preconditions.checkState(defaultTimeoutMillis > 0, "Expected default timeout to be positive");

    this.workDir = workDir;
    this.binaryPath = binaryPath;
    this.env = Maps.newHashMap(env);
    this.executorService = executorService;
    this.timeoutMillis = defaultTimeoutMillis;
  }

  /**
   * Sets environment variable for the Bazel invocation.
   *
   * @param name name of the variable
   * @param value value of variable
   * @return this BuildRunner instance
   */
  public BuilderRunner withEnv(String name, String value) {
    env.put(name, value);
    return this;
  }

  /**
   * Sets timeout value for the Bazel process invocation. If not called, default value is used,
   * which is calculated from the test parameters. See {@link
   * BlackBoxTestContext#getTestTimeoutMillis()}. If the invocation time exceeds timeout, {@link
   * TimeoutException} is thrown.
   *
   * @param timeoutMillis timeout value in milliseconds
   * @return this BuilderRunner instance
   */
  public BuilderRunner withTimeout(long timeoutMillis) {
    Preconditions.checkState(this.timeoutMillis > 0);
    this.timeoutMillis = timeoutMillis;
    return this;
  }

  /**
   * Specifies that Bazel should not pass the default .bazelrc (in the test working directory) as
   * parameter
   *
   * @return this BuilderRunner instance
   */
  public BuilderRunner withoutDefaultRc() {
    useDefaultRc = false;
    return this;
  }

  /**
   * Runs <code>bazel info &lt;parameter&gt;</code> and returns the result. Asserts that the process
   * exit code is zero. Does not assert that the error stream is empty.
   *
   * @param parameter info command parameter
   * @return ProcessResult with process exit code, strings with stdout and error streams contents
   * @throws TimeoutException in case of timeout
   * @throws IOException in case of the process startup/interaction problems
   * @throws InterruptedException if the current thread is interrupted while waiting
   * @throws ProcessRunnerException if the process return code is not zero or error stream is not
   *     empty when it was expected
   */
  public ProcessResult info(String parameter) throws Exception {
    // additional expectations for the info time to be under the default timeout
    withTimeout(Math.min(DEFAULT_TIMEOUT_MILLIS, timeoutMillis));
    return runBinary("info", parameter);
  }

  /**
   * Runs <code>bazel test &lt;args&gt;</code> and returns the result. Asserts that the process exit
   * code is zero. Does not assert that the error stream is empty.
   *
   * @param args arguments to pass to test command
   * @return ProcessResult with process exit code, strings with stdout and error streams contents
   * @throws TimeoutException in case of timeout
   * @throws IOException in case of the process startup/interaction problems
   * @throws InterruptedException if the current thread is interrupted while waiting
   * @throws ProcessRunnerException if the process return code is not zero or error stream is not
   *     empty when it was expected
   */
  public ProcessResult test(String... args) throws Exception {
    return runBinary("test", args);
  }

  /**
   * Runs <code>bazel build &lt;args&gt;</code> and returns the result. Asserts that the process
   * exit code is zero. Does not assert that the error stream is empty.
   *
   * @param args arguments to pass to build command
   * @return ProcessResult with process exit code, strings with stdout and error streams contents
   * @throws TimeoutException in case of timeout
   * @throws IOException in case of the process startup/interaction problems
   * @throws InterruptedException if the current thread is interrupted while waiting
   * @throws ProcessRunnerException if the process return code is not zero or error stream is not
   *     empty when it was expected
   */
  public ProcessResult build(String... args) throws Exception {
    return runBinary("build", args);
  }

  /**
   * Runs <code>bazel run &lt;args&gt;</code> and returns the result. Asserts that the process exit
   * code is zero. Does not assert that the error stream is empty.
   *
   * @param args arguments to pass to run command
   * @return ProcessResult with process exit code, strings with stdout and error streams contents
   * @throws TimeoutException in case of timeout
   * @throws IOException in case of the process startup/interaction problems
   * @throws InterruptedException if the current thread is interrupted while waiting
   * @throws ProcessRunnerException if the process return code is not zero or error stream is not
   *     empty when it was expected
   */
  public ProcessResult run(String... args) throws Exception {
    return runBinary("run", args);
  }

  /**
   * Runs <code>bazel shutdown</code> and returns the result. Asserts that the process exit code is
   * zero. Does not assert that the error stream is empty.
   *
   * @return ProcessResult with process exit code, strings with stdout and error streams contents
   * @throws TimeoutException in case of timeout
   * @throws IOException in case of the process startup/interaction problems
   * @throws InterruptedException if the current thread is interrupted while waiting
   * @throws ProcessRunnerException if the process return code is not zero or error stream is not
   *     empty when it was expected
   */
  public ProcessResult shutdown() throws Exception {
    // additional expectations for the shutdown time to be under the default timeout
    withTimeout(Math.min(DEFAULT_TIMEOUT_MILLIS, timeoutMillis));
    return runBinary("shutdown");
  }

  private ProcessResult runBinary(String command, String... args) throws Exception {
    List<String> list = Lists.newArrayList();

    if (useDefaultRc) {
      Path bazelRc = workDir.resolve(".bazelrc");
      if (Files.exists(bazelRc)) {
        list.add("--bazelrc");
        list.add(bazelRc.toAbsolutePath().toString());
      }
    }
    list.add(command);
    Collections.addAll(list, args);

    ProcessParameters parameters =
        ProcessParameters.builder()
            .setWorkingDirectory(workDir.toFile())
            .setName(binaryPath.toString())
            .setTimeoutMillis(timeoutMillis)
            .setArguments(list)
            .setEnvironment(ImmutableMap.copyOf(env))
            // bazel writes info messages to error stream, so
            // we need to allow the error output stream be not empty
            .setExpectedEmptyError(false)
            .build();
    return new ProcessRunner(parameters, executorService).runSynchronously();
  }
}
