// Copyright 2011 Google Inc. 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.enterprise.adaptor.prebuilt;

import java.io.*;

/**
 * Exec helper that allows easy handling of stdin, stdout, and stderr. Normally
 * you have to worry about deadlock when dealing with those streams (as
 * mentioned briefly in {@link Process}), so this class handles that for you.
 */
public class Command {
  // Prevent instantiation.
  private Command() {}

  /**
   * Same as {@code exec(command, null, new byte[0])}.
   *
   */
  public static Result exec(String[] command) throws IOException,
         InterruptedException {
    return exec(command, null, new byte[0]);
  }

  /**
   * Same as {@code exec(command, workingDir, new byte[0])}.
   *
   * @see #exec(String[], File, byte[])
   */
  public static Result exec(String[] command, File workingDir)
      throws IOException, InterruptedException {
    return exec(command, workingDir, new byte[0]);
  }

  /**
   * Same as {@code exec(command, null, stdin)}.
   *
   * @see #exec(String[], File, byte[])
   */
  public static Result exec(String[] command, byte[] stdin) throws IOException,
         InterruptedException {
    return exec(command, null, stdin);
  }

  /**
   * Create process {@code command} starting in the {@code workingDir} and
   * providing {@code stdin} as input. This method blocks until the process
   * exits. Stdout and stderr are available via {@link Result#getStdout} and
   * {@link Result#getStderr}. Before using them, however, you should generally
   * make sure that the process exited with a return code of zero, as other
   * return codes typically indicate an error.
   *
   * @throws IOException if creating process fails
   */
  public static Result exec(String[] command, File workingDir, byte[] stdin)
      throws IOException, InterruptedException {
    ByteArrayOutputStream outBuffer = new ByteArrayOutputStream();
    ByteArrayOutputStream errBuffer = new ByteArrayOutputStream();

    int returnCode = StreamingCommand.exec(command, workingDir,
        StreamingCommand.streamInputSource(new ByteArrayInputStream(stdin)),
        StreamingCommand.streamOutputSink(outBuffer),
        StreamingCommand.streamOutputSink(errBuffer));

    byte[] stdout = outBuffer.toByteArray();
    byte[] stderr = errBuffer.toByteArray();

    return new Result(returnCode, stdout, stderr);
  }

  /**
   * Result data from an invocation
   */
  public static class Result {
    private final int returnCode;
    private final byte[] stdout;
    private final byte[] stderr;

    /**
     * Construct a result. In normal usage, this is unnecessary, but it can be
     * helpful in the tests of classes that use {@code Command}.
     */
    public Result(int returnCode, byte[] stdout, byte[] stderr) {
      if (stdout == null || stderr == null) {
        throw new NullPointerException();
      }
      this.returnCode = returnCode;
      this.stdout = stdout;
      this.stderr = stderr;
    }

    public int getReturnCode() {
      return returnCode;
    }

    /**
     * Returns internal byte array without copying.
     */
    public byte[] getStdout() {
      return stdout;
    }

    /**
     * Returns internal byte array without copying.
     */
    public byte[] getStderr() {
      return stderr;
    }
  }
}
