// 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.shell;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;
import javax.annotation.Nullable;

/**
 * A builder class that starts a subprocess.
 */
public class SubprocessBuilder {
  /**
   * What to do with an output stream of the process.
   */
  public enum StreamAction {
    /** Redirect to a file */
    REDIRECT,

    /** Discard. */
    DISCARD,

    /** Stream back to the parent process using an output stream. */
    STREAM
  }

  private final SubprocessFactory factory;
  private ImmutableList<String> argv;
  private ImmutableMap<String, String> env;
  private StreamAction stdoutAction;
  private File stdoutFile;
  private StreamAction stderrAction;
  private File stderrFile;
  private File workingDirectory;
  private long timeoutMillis;
  private boolean redirectErrorStream;

  static SubprocessFactory defaultFactory = JavaSubprocessFactory.INSTANCE;

  public static void setDefaultSubprocessFactory(SubprocessFactory factory) {
    SubprocessBuilder.defaultFactory = factory;
  }

  public SubprocessBuilder() {
    this(defaultFactory);
  }

  public SubprocessBuilder(SubprocessFactory factory) {
    stdoutAction = StreamAction.STREAM;
    stderrAction = StreamAction.STREAM;
    this.factory = factory;
  }

  /**
   * Returns the complete argv, including argv0.
   *
   * <p>argv[0] is either absolute (e.g. "/foo/bar" or "c:/foo/bar.exe"), or is a single file name
   * (no directory component, e.g. "true" or "cmd.exe"). It might be non-normalized though (e.g.
   * "/foo/../bar/./baz").
   */
  public ImmutableList<String> getArgv() {
    return argv;
  }

  /**
   * Sets the argv, including argv[0], that is, the binary to execute.
   *
   * <p>argv[0] must be either absolute (e.g. "/foo/bar" or "c:/foo/bar.exe"), or a single file name
   * (no directory component, e.g. "true" or "cmd.exe") which should be on the OS-specific search
   * path (PATH on Unixes, Windows-specific lookup paths on Windows).
   *
   * @throws IllegalArgumentException if argv is empty, or its first element (which becomes
   *     this.argv[0]) is neither an absolute path nor just a single file name
   */
  public SubprocessBuilder setArgv(Iterable<String> argv) {
    this.argv = ImmutableList.copyOf(argv);
    Preconditions.checkArgument(!this.argv.isEmpty());
    File argv0 = new File(this.argv.get(0));
    Preconditions.checkArgument(
        argv0.isAbsolute() || argv0.getParent() == null,
        "argv[0] = '%s'; it should be either absolute or just a single file name"
            + " (no directory component)",
        this.argv.get(0));
    return this;
  }

  public SubprocessBuilder setArgv(String... argv) {
    this.setArgv(Arrays.asList(argv));
    return this;
  }

  public ImmutableMap<String, String> getEnv() {
    return env;
  }

  /**
   * Sets the environment passed to the child process. If null, inherit the environment of the
   * server.
   */
  public SubprocessBuilder setEnv(@Nullable Map<String, String> env) {
    this.env = env == null ? null : ImmutableMap.copyOf(env);
    return this;
  }

  public StreamAction getStdout() {
    return stdoutAction;
  }

  public File getStdoutFile() {
    return stdoutFile;
  }

  /**
   * Tells the object what to do with stdout: either stream as a {@code InputStream} or discard.
   *
   * <p>It can also be redirected to a file using {@link #setStdout(File)}.
   */
  public SubprocessBuilder setStdout(StreamAction action) {
    if (action == StreamAction.REDIRECT) {
      throw new IllegalStateException();
    }
    this.stdoutAction = action;
    this.stdoutFile = null;
    return this;
  }

  /**
   * Sets the file stdout is appended to. If null, the stdout will be available as an input stream
   * on the resulting object representing the process.
   */
  public SubprocessBuilder setStdout(File file) {
    this.stdoutAction = StreamAction.REDIRECT;
    this.stdoutFile = file;
    return this;
  }

  public SubprocessBuilder setTimeoutMillis(long timeoutMillis) {
    this.timeoutMillis = timeoutMillis;
    return this;
  }

  public long getTimeoutMillis() {
    return timeoutMillis;
  }

  public StreamAction getStderr() {
    return stderrAction;
  }

  public File getStderrFile() {
    return stderrFile;
  }

  /**
   * Tells the object what to do with stderr: either stream as a {@code InputStream} or discard.
   *
   * <p>It can also be redirected to a file using {@link #setStderr(File)}.
   */
  public SubprocessBuilder setStderr(StreamAction action) {
    if (action == StreamAction.REDIRECT) {
      throw new IllegalStateException();
    }
    this.stderrAction = action;
    this.stderrFile = null;
    return this;
  }

  /**
   * Sets the file stderr is appended to. If null, the stderr will be available as an input stream
   * on the resulting object representing the process. When {@code redirectErrorStream} is set to
   * True, this method has no effect.
   */
  public SubprocessBuilder setStderr(File file) {
    this.stderrAction = StreamAction.REDIRECT;
    this.stderrFile = file;
    return this;
  }

  /**
   * Tells whether this process builder merges standard error and standard output.
   *
   * @return this process builder's {@code redirectErrorStream} property
   */
  public boolean redirectErrorStream() {
    return redirectErrorStream;
  }

  /**
   * Sets whether this process builder merges standard error and standard output.
   *
   * <p>If this property is {@code true}, then any error output generated by subprocesses
   * subsequently started by this object's {@link #start()} method will be merged with the standard
   * output, so that both can be read using the {@link Subprocess#getInputStream()} method. This
   * makes it easier to correlate error messages with the corresponding output. The initial value is
   * {@code false}.
   */
  public SubprocessBuilder redirectErrorStream(boolean redirectErrorStream) {
    this.redirectErrorStream = redirectErrorStream;
    return this;
  }

  public File getWorkingDirectory() {
    return workingDirectory;
  }

  /**
   * Sets the current working directory. If null, it will be that of this process.
   */
  public SubprocessBuilder setWorkingDirectory(File workingDirectory) {
    this.workingDirectory = workingDirectory;
    return this;
  }

  public Subprocess start() throws IOException {
    return factory.create(this);
  }
}
