//
// Copyright (C) 2011 The Android Open Source Project
//
// 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.
//

#ifndef UPDATE_ENGINE_COMMON_SUBPROCESS_H_
#define UPDATE_ENGINE_COMMON_SUBPROCESS_H_

#include <unistd.h>

#include <map>
#include <memory>
#include <string>
#include <vector>

#include <base/callback.h>
#include <base/files/file_descriptor_watcher_posix.h>
#include <base/logging.h>
#include <base/macros.h>
#include <brillo/asynchronous_signal_handler_interface.h>
#include <brillo/message_loops/message_loop.h>
#ifdef __CHROMEOS__
#include <brillo/process/process.h>
#include <brillo/process/process_reaper.h>
#else
#include <brillo/process.h>
#include <brillo/process_reaper.h>
#endif  // __CHROMEOS__
#include <gtest/gtest_prod.h>

// The Subprocess class is a singleton. It's used to spawn off a subprocess
// and get notified when the subprocess exits. The result of Exec() can
// be saved and used to cancel the callback request and kill your process. If
// you know you won't call KillExec(), you may safely lose the return value
// from Exec().

// To create the Subprocess singleton just instantiate it with and call Init().
// You can't have two Subprocess instances initialized at the same time.

namespace chromeos_update_engine {

class Subprocess {
 public:
  enum Flags {
    kSearchPath = 1 << 0,
    kRedirectStderrToStdout = 1 << 1,
  };

  // Callback type used when an async process terminates. It receives the exit
  // code and the stdout output (and stderr if redirected).
  using ExecCallback = base::Callback<void(int, const std::string&)>;

  Subprocess() = default;

  // Destroy and unregister the Subprocess singleton.
  ~Subprocess();

  // Initialize and register the Subprocess singleton.
  void Init(brillo::AsynchronousSignalHandlerInterface* async_signal_handler);

  // Launches a process in the background and calls the passed |callback| when
  // the process exits. The file descriptors specified in |output_pipes| will
  // be available in the child as the writer end of a pipe. Use GetPipeFd() to
  // know the reader end in the parent. Only stdin, stdout, stderr and the file
  // descriptors in |output_pipes| will be open in the child.
  // Returns the process id of the new launched process or 0 in case of failure.
  pid_t Exec(const std::vector<std::string>& cmd, const ExecCallback& callback);
  pid_t ExecFlags(const std::vector<std::string>& cmd,
                  uint32_t flags,
                  const std::vector<int>& output_pipes,
                  const ExecCallback& callback);

  // Kills the running process with SIGTERM and ignores the callback.
  void KillExec(pid_t pid);

  // Return the parent end of the pipe mapped onto |fd| in the child |pid|. This
  // file descriptor is available until the callback for the child |pid|
  // returns. After that the file descriptor will be closed. The passed |fd|
  // must be one of the file descriptors passed to ExecFlags() in
  // |output_pipes|, otherwise returns -1.
  int GetPipeFd(pid_t pid, int fd) const;

  // Executes a command synchronously. Returns true on success. If |stdout_str|
  // is non-null, the process output is stored in it, otherwise the output is
  // logged.
  static bool SynchronousExec(const std::vector<std::string>& cmd,
                              int* return_code,
                              std::string* stdout_str,
                              std::string* stderr_str);
  static bool SynchronousExecFlags(const std::vector<std::string>& cmd,
                                   uint32_t flags,
                                   int* return_code,
                                   std::string* stdout_str,
                                   std::string* stderr_str);

  // Gets the one instance.
  static Subprocess& Get() { return *subprocess_singleton_; }

  // Tries to log all in flight processes's output. It is used right before
  // exiting the update_engine, probably when the subprocess caused a system
  // shutdown.
  void FlushBufferedLogsAtExit();

 private:
  FRIEND_TEST(SubprocessTest, CancelTest);

  struct SubprocessRecord {
    explicit SubprocessRecord(const ExecCallback& callback)
        : callback(callback) {}

    // The callback supplied by the caller.
    ExecCallback callback;

    // The ProcessImpl instance managing the child process. Destroying this
    // will close our end of the pipes we have open.
    brillo::ProcessImpl proc;

    // These are used to monitor the stdout of the running process, including
    // the stderr if it was redirected.
    std::unique_ptr<base::FileDescriptorWatcher::Controller> stdout_controller;

    int stdout_fd{-1};
    std::string stdout_str;
  };

  // Callback which runs whenever there is input available on the subprocess
  // stdout pipe.
  static void OnStdoutReady(SubprocessRecord* record);

  // Callback for when any subprocess terminates. This calls the user
  // requested callback.
  void ChildExitedCallback(const siginfo_t& info);

  // The global instance.
  static Subprocess* subprocess_singleton_;

  // A map from the asynchronous subprocess tag (see Exec) to the subprocess
  // record structure for all active asynchronous subprocesses.
  std::map<pid_t, std::unique_ptr<SubprocessRecord>> subprocess_records_;

  // Used to watch for child processes.
  brillo::ProcessReaper process_reaper_;

  DISALLOW_COPY_AND_ASSIGN(Subprocess);
};

}  // namespace chromeos_update_engine

#endif  // UPDATE_ENGINE_COMMON_SUBPROCESS_H_
