// 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.bazel.e4b.command;

import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.devtools.bazel.e4b.command.CommandConsole.CommandConsoleFactory;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.function.Function;

/**
 * A utility class to spawn a command and parse its output. It allow to filter the output,
 * redirecting part of it to the console and getting the rest in a list of string.
 *
 * <p>
 * This class can only be initialized using a builder created with the {@link #builder()} method.
 */
final class Command {

  // TODO: inject
  private final CommandConsoleFactory consoleFactory = new CommandConsoleFactoryImpl();

  private final File directory;
  private final ImmutableList<String> args;
  private final SelectOutputStream stdout;
  private final SelectOutputStream stderr;
  private boolean executed = false;

  private Command(String consoleName, File directory, ImmutableList<String> args,
      Function<String, String> stdoutSelector, Function<String, String> stderrSelector,
      OutputStream stdout, OutputStream stderr) throws IOException {
    this.directory = directory;
    this.args = args;
    if (consoleName != null) {
      CommandConsole console = consoleFactory.get(consoleName,
          "Running " + String.join(" ", args) + " from " + directory.toString());
      if (stdout == null) {
        stdout = console.createOutputStream();
      }
      if (stderr == null) {
        stderr = console.createErrorStream();
      }
    }
    this.stderr = new SelectOutputStream(stderr, stderrSelector);
    this.stdout = new SelectOutputStream(stdout, stdoutSelector);
  }

  /**
   * Executes the command represented by this instance, and return the exit code of the command.
   * This method should not be called twice on the same object.
   */
  public int run() throws IOException, InterruptedException {
    Preconditions.checkState(!executed);
    executed = true;
    ProcessBuilder builder = new ProcessBuilder(args);
    builder.directory(directory);
    Process process = builder.start();
    copyStream(process.getErrorStream(), stderr);
    // seriously? That's stdout, why is it called getInputStream???
    copyStream(process.getInputStream(), stdout);
    int r = process.waitFor();
    synchronized (stderr) {
      stderr.close();
    }
    synchronized (stdout) {
      stdout.close();
    }
    return r;
  }

  // Launch a thread to copy all data from inputStream to outputStream
  private static void copyStream(InputStream inputStream, OutputStream outputStream) {
    if (outputStream != null) new Thread(new Runnable() {
      @Override
      public void run() {
        byte[] buffer = new byte[4096];
        int read;
        try {
          while ((read = inputStream.read(buffer)) > 0) {
            synchronized (outputStream) {
              outputStream.write(buffer, 0, read);
            }
          }
        } catch (IOException ex) {
          // we simply terminate the thread on exceptions
        }
      }
    }).start();
  }

  /**
   * Returns the list of lines selected from the standard error stream. Lines printed to the
   * standard error stream by the executed command can be filtered to be added to that list.
   *
   * @see {@link Builder#setStderrLineSelector(Function)}
   */
  ImmutableList<String> getSelectedErrorLines() {
    return stderr.getLines();
  }

  /**
   * Returns the list of lines selected from the standard output stream. Lines printed to the
   * standard output stream by the executed command can be filtered to be added to that list.
   *
   * @see {@link Builder#setStdoutLineSelector(Function)}
   */
  ImmutableList<String> getSelectedOutputLines() {
    return stdout.getLines();
  }

  /**
   * A builder class to generate a Command object.
   */
  static class Builder {

    private String consoleName = null;
    private File directory;
    private ImmutableList.Builder<String> args = ImmutableList.builder();
    private OutputStream stdout = null;
    private OutputStream stderr = null;
    private Function<String, String> stdoutSelector;
    private Function<String, String> stderrSelector;

    private Builder() {
      // Default to the current working directory
      this.directory = new File(System.getProperty("user.dir"));
    }

    /**
     * Set the console name.
     *
     * <p>
     * The console name is used to print result of the program. Only lines not filtered by
     * {@link #setStderrLineSelector(Function)} and {@link #setStdoutLineSelector(Function)} are
     * printed to the console. If {@link #setStandardError(OutputStream)} or
     * {@link #setStandardOutput(OutputStream)} have been used with a non null value, then they
     * intercept all output from being printed to the console.
     *
     * <p>
     * If name is null, no output is written to any console.
     */
    public Builder setConsoleName(String name) {
      this.consoleName = name;
      return this;
    }

    /**
     * Set the working directory for the program, it is set to the current working directory of the
     * current java process by default.
     */
    public Builder setDirectory(File directory) {
      this.directory = directory;
      return this;
    }

    /**
     * Set an {@link OutputStream} to receive non selected lines from the standard output stream of
     * the program in lieu of the console. If a selector has been set with
     * {@link #setStdoutLineSelector(Function)}, only the lines not selected (for which the selector
     * returns null) will be printed to the {@link OutputStream}.
     */
    public Builder setStandardOutput(OutputStream stdout) {
      this.stdout = stdout;
      return this;
    }

    /**
     * Set an {@link OutputStream} to receive non selected lines from the standard error stream of
     * the program in lieu of the console. If a selector has been set with
     * {@link #setStderrLineSelector(Function)}, only the lines not selected (for which the selector
     * returns null) will be printed to the {@link OutputStream}.
     */
    public Builder setStandardError(OutputStream stderr) {
      this.stderr = stderr;
      return this;
    }

    /**
     * Add arguments to the command line. The first argument to be added to the builder is the
     * program name.
     */
    public Builder addArguments(String... args) {
      this.args.add(args);
      return this;
    }

    /**
     * Add a list of arguments to the command line. The first argument to be added to the builder is
     * the program name.
     */
    public Builder addArguments(Iterable<String> args) {
      this.args.addAll(args);
      return this;
    }

    /**
     * Set a selector to accumulate lines that are selected from the standard output stream.
     *
     * <p>
     * The selector is passed all lines that are printed to the standard output. It can either
     * returns null to say that the line should be passed to the console or to a non null value that
     * will be stored. All values that have been selected (for which the selector returns a non-null
     * value) will be stored in a list accessible through {@link Command#getSelectedOutputLines()}.
     * The selected lines will not be printed to the console.
     */
    public Builder setStdoutLineSelector(Function<String, String> selector) {
      this.stdoutSelector = selector;
      return this;
    }

    /**
     * Set a selector to accumulate lines that are selected from the standard error stream.
     *
     * <p>
     * The selector is passed all lines that are printed to the standard error. It can either
     * returns null to say that the line should be passed to the console or to a non null value that
     * will be stored. All values that have been selected (for which the selector returns a non-null
     * value) will be stored in a list accessible through {@link Command#getSelectedErrorLines()}.
     * The selected lines will not be printed to the console.
     */
    public Builder setStderrLineSelector(Function<String, String> selector) {
      this.stderrSelector = selector;
      return this;
    }

    /**
     * Build a Command object.
     */
    public Command build() throws IOException {
      Preconditions.checkNotNull(directory);
      return new Command(consoleName, directory, args.build(), stdoutSelector, stderrSelector,
          stdout, stderr);
    }
  }

  /**
   * Returns a {@link Builder} object to use to create a {@link Command} object.
   */
  static Builder builder() {
    return new Builder();
  }
}
