// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CROS_DISKS_PROCESS_H_
#define CROS_DISKS_PROCESS_H_

#include <string>
#include <utility>
#include <vector>

#include <base/files/scoped_file.h>
#include <base/macros.h>
#include <base/strings/string_piece.h>

#include <gtest/gtest_prod.h>

namespace cros_disks {

// A base class for executing a process.
//
// TODO(crbug.com/1003654) This base class is not feature complete yet.
class Process {
 public:
  // Invalid process ID assigned to a process that has not started.
  static const pid_t kInvalidProcessId;

  static const int kInvalidFD;

  virtual ~Process();

  // Adds an argument to the end of the argument list.
  // Precondition: Start() has not been called yet.
  void AddArgument(std::string argument);

  // Adds a variable to the environment that will be passed to the process.
  // Precondition: Start() has not been called yet.
  // Precondition: `name` is not empty and doesn't contain '='.
  void AddEnvironmentVariable(base::StringPiece name, base::StringPiece value);

  // Sets the string to pass to the process stdin.
  // Might be silently truncated if it doesn't fit in a pipe's buffer.
  // Precondition: Start() has not been called yet.
  void SetStdIn(std::string input) { input_ = std::move(input); }

  // Starts the process. The started process has its stdin, stdout and stderr
  // connected to /dev/null. Returns true in case of success. Once started, the
  // process can be waiting for to finish using Wait().
  bool Start();

  // Waits for the process to finish and returns its exit status.
  int Wait();

  // Checks if the process finished.
  bool IsFinished();

  // Starts a process, captures its output and waits for it to finish. Returns
  // the same exit status as Wait().
  //
  // Precondition: output is non-null
  int Run(std::vector<std::string>* output);

  pid_t pid() const { return pid_; }

  const std::vector<std::string>& arguments() const { return arguments_; }
  const std::vector<std::string>& environment() const { return environment_; }
  const std::string& input() const { return input_; }

 protected:
  Process();

  // Gets the arguments used to start the process. This method calls
  // BuildArgumentsArray() to build |arguments_array_| only once (i.e. when
  // |arguments_array_| is empty). Once |arguments_array_| is built, subsequent
  // calls to AddArgument() are not allowed. The returned array of arguments is
  // owned by this Process object.
  char* const* GetArguments();

  // Gets the environment to pass to the subprocess. The returned array of
  // environment variables is owned by this Process object.
  char* const* GetEnvironment();

  // Starts a process, and connects to its stdin, stdout and stderr the given
  // file descriptors.
  //
  // Returns the PID of the started process, or -1 in case of error.
  virtual pid_t StartImpl(base::ScopedFD in_fd,
                          base::ScopedFD out_fd,
                          base::ScopedFD err_fd) = 0;

  // Once either WaitImpl() or WaitNonBlockingImpl() has returned a nonnegative
  // exit status, none of these methods is called again.

  // Waits for the process to finish and returns its nonnegative exit status.
  virtual int WaitImpl() = 0;

  // Checks if the process has finished and returns its nonnegative exit status,
  // or -1 if the process is still running.
  virtual int WaitNonBlockingImpl() = 0;

 private:
  // Starts the process. The started process has its stdin, stdout and stderr
  // redirected to the given file descriptors. Returns true in case of success.
  bool Start(base::ScopedFD in_fd,
             base::ScopedFD out_fd,
             base::ScopedFD err_fd);

  // Waits for process to finish collecting process' stdout and stderr
  // output and fills interleaved version of it.
  void Communicate(std::vector<std::string>* output,
                   base::ScopedFD out_fd,
                   base::ScopedFD err_fd);

  // Builds |arguments_array_| from |arguments_|. Existing values of
  // |arguments_array_| are overridden.
  void BuildArgumentsArray();

  bool finished() const { return status_ >= 0; }

  // Process arguments.
  std::vector<std::string> arguments_;
  std::vector<char*> arguments_array_;

  // Extra environment variables.
  std::vector<std::string> environment_;

  // Full environment for the subprocess.
  std::vector<char*> environment_array_;

  // String to pass to the process stdin.
  std::string input_;

  // Process ID (default to kInvalidProcessId when the process has not started).
  pid_t pid_ = kInvalidProcessId;

  // Exit status. A nonnegative value indicates that the process has finished.
  int status_ = -1;

  FRIEND_TEST(ProcessTest, GetArguments);
  FRIEND_TEST(ProcessTest, GetArgumentsWithNoArgumentsAdded);

  DISALLOW_COPY_AND_ASSIGN(Process);
};

}  // namespace cros_disks

#endif  // CROS_DISKS_PROCESS_H_
