// Copyright 2018 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 SHILL_PROCESS_MANAGER_H_
#define SHILL_PROCESS_MANAGER_H_

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

#include <base/callback.h>
#include <base/cancelable_callback.h>
#include <base/files/file_path.h>
#include <base/lazy_instance.h>
#include <base/memory/weak_ptr.h>
#include <base/tracked_objects.h>
#include <brillo/minijail/minijail.h>
#include <brillo/process.h>
#include <brillo/process_reaper.h>
#include <libminijail.h>

namespace shill {

struct std_file_descriptors {
  int* stdin_fd;
  int* stdout_fd;
  int* stderr_fd;
};

class EventDispatcher;

// The ProcessManager is a singleton providing process creation and
// asynchronous process termination. Need to initialize it once with
// Init method call.
class ProcessManager {
 public:
  virtual ~ProcessManager();

  // This is a singleton -- use ProcessManager::GetInstance()->Foo().
  static ProcessManager* GetInstance();

  // Register async signal handler and setup process reaper.
  virtual void Init(EventDispatcher* dispatcher);

  // Call on shutdown to release async_signal_handler_.
  virtual void Stop();

  // Create and start a process for |program| with |arguments|. |environment|
  // variables will be setup in the child process before exec the |program|.
  // |terminate_with_parent| is used to indicate if child process should
  // self terminate if the parent process exits.  |exit_callback| will be
  // invoked when child process exits (not terminated by us).  Return -1
  // if failed to start the process, otherwise, return the pid of the child
  // process.
  virtual pid_t StartProcess(
      const tracked_objects::Location& spawn_source,
      const base::FilePath& program,
      const std::vector<std::string>& arguments,
      const std::map<std::string, std::string>& environment,
      bool terminate_with_parent,
      const base::Callback<void(int)>& exit_callback);

  // Similar to StartProcess(), with the following differences:
  // - environment variables are not supported (no need yet)
  // - terminate_with_parent is not supported (may be non-trivial)
  // - the child process will run as |user| and |group|
  // - the |capmask| argument can be used to provide the child process
  //   with capabilities, which |user| might not have on its own
  // - the |inherit_supplementary_groups| argument allows child process to
  //   inherit supplementary groups from uid, equivalent to using '-G' on the
  //   minijail command line.
  virtual pid_t StartProcessInMinijail(
      const tracked_objects::Location& spawn_source,
      const base::FilePath& program,
      const std::vector<std::string>& arguments,
      const std::string& user,
      const std::string& group,
      uint64_t capmask,
      bool inherit_supplementary_groups,
      bool close_nonstd_fds,
      const base::Callback<void(int)>& exit_callback) {
    return StartProcessInMinijailWithPipes(
        spawn_source, program, arguments, user, group, capmask,
        inherit_supplementary_groups, close_nonstd_fds, exit_callback,
        (struct std_file_descriptors){nullptr, nullptr, nullptr});
  }

  // Similar to StartProcessInMinijail(), with the additional ability to
  // pipe the child's stdin/stdout/stderr back to us. If any of those
  // streams is not needed, simply pass nullptr for the corresponding
  // member in std file descriptor struct. If no pipes are needed, use
  // StartProcessInMinijail().
  virtual pid_t StartProcessInMinijailWithPipes(
      const tracked_objects::Location& spawn_source,
      const base::FilePath& program,
      const std::vector<std::string>& arguments,
      const std::string& user,
      const std::string& group,
      uint64_t capmask,
      bool inherit_supplementary_groups,
      bool close_nonstd_fds,
      const base::Callback<void(int)>& exit_callback,
      struct std_file_descriptors std_fds);

  // Stop the given |pid|.  Previously registered |exit_callback| will be
  // unregistered, since the caller is not interested in this process anymore
  // and that callback might not be valid by the time this process terminates.
  // This will attempt to terminate the child process by sending a SIGTERM
  // signal first.  If the process doesn't terminate within a certain time,
  // ProcessManager will attempt to send a SIGKILL signal.  It will give up
  // with an error log If the process still doesn't terminate within a certain
  // time.
  virtual bool StopProcess(pid_t pid);

  // Stop the given |pid| in a synchronous manner.
  virtual bool StopProcessAndBlock(pid_t pid);

  // Replace the current exit callback for |pid| with |new_callback|.
  virtual bool UpdateExitCallback(
      pid_t pid,
      const base::Callback<void(int)>& new_callback);

 protected:
  ProcessManager();

 private:
  friend class ProcessManagerTest;
  friend base::LazyInstanceTraitsBase<ProcessManager>;

  using TerminationTimeoutCallback = base::CancelableClosure;

  // Invoked when process |pid| exited.
  void OnProcessExited(pid_t pid, const siginfo_t& info);

  // Invoked when process |pid| did not terminate within a certain timeout.
  // |kill_signal| indicates the signal used for termination. When it is set
  // to true, SIGKILL was used to terminate the process, otherwise, SIGTERM
  // was used.
  void ProcessTerminationTimeoutHandler(pid_t pid, bool kill_signal);

  // Send a termination signal to process |pid|. If |kill_signal| is set to
  // true, SIGKILL is sent, otherwise, SIGTERM is sent.  After signal is sent,
  // |pid| and timeout handler is added to |pending_termination_processes_|
  // list, to make sure process |pid| does exit in timely manner.
  bool TerminateProcess(pid_t pid, bool kill_signal);

  // Kill process |pid|. If |kill_signal| is true it will send SIGKILL,
  // otherwise it will send SIGTERM.
  // It returns true when the process was already dead or killed within
  // the timeout.
  // It returns false when the process failed to exit within the timeout
  // or the system failed to send kill singal.
  bool KillProcessWithTimeout(pid_t pid, bool kill_signal);

  // Kill process |pid| using signal |signal|.
  // The |killed| will be set true when the process was already dead.
  // It returns true when it sent the |signal| successfully or the
  // process was already dead.
  // It returns false when the system failed to send |signal|.
  bool KillProcess(pid_t pid, int signal, bool* killed);

  // Wait for process |pid| to exit. This function will check it for at most
  // |tries| times. The interval of waiting time grows exponentially from
  // |sleep_ms| and it has an |upper_bound_ms| upper bound.
  bool WaitpidWithTimeout(pid_t pid,
                          unsigned int sleep_ms,
                          unsigned int upper_bound_ms,
                          int tries);

  // Used to watch processes.
  std::unique_ptr<brillo::AsynchronousSignalHandler> async_signal_handler_;
  brillo::ProcessReaper process_reaper_;

  EventDispatcher* dispatcher_;
  brillo::Minijail* minijail_;

  // Processes to watch for the caller.
  std::map<pid_t, base::Callback<void(int)>> watched_processes_;
  // Processes being terminated by us.  Use a timer to make sure process
  // does exit, log an error if it failed to exit within a specific timeout.
  std::map<pid_t, std::unique_ptr<TerminationTimeoutCallback>>
      pending_termination_processes_;

  base::WeakPtrFactory<ProcessManager> weak_factory_{this};
  DISALLOW_COPY_AND_ASSIGN(ProcessManager);
};

}  // namespace shill

#endif  // SHILL_PROCESS_MANAGER_H_
