// Copyright 2016 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "patchpanel/subprocess_controller.h"

#include <signal.h>
#include <string.h>
#include <unistd.h>

#include <utility>

#include <base/check.h>
#include <base/check_op.h>
#include <base/logging.h>
#include <base/process/launch.h>
#include <base/task/single_thread_task_runner.h>
#include <brillo/syslog_logging.h>
#include <chromeos/net-base/process_manager.h>

#include "patchpanel/ipc.h"
#include "patchpanel/system.h"

namespace patchpanel {
namespace {
// Maximum tries of restart.
constexpr int kMaxRestarts = 5;
// The delay of the first round of restart.
constexpr int kSubprocessRestartDelayMs = 900;
}  // namespace

SubprocessController::SubprocessController(
    System* system,
    net_base::ProcessManager* process_manager,
    const base::FilePath& cmd_path,
    const std::string& fd_arg)
    : system_(system),
      process_manager_(process_manager),
      cmd_path_(cmd_path),
      fd_arg_(fd_arg) {}

SubprocessController::~SubprocessController() {
  if (pid_) {
    process_manager_->StopProcess(*pid_);
  }
}

void SubprocessController::Start() {
  if (pid_) {
    LOG(ERROR) << "The process is already running, ignore";
    return;
  }

  int control[2];

  if (system_->SocketPair(AF_UNIX, SOCK_SEQPACKET, 0, control) != 0) {
    PLOG(FATAL) << "socketpair failed";
  }

  base::ScopedFD control_fd(control[0]);
  msg_dispatcher_ = std::make_unique<MessageDispatcher<SubprocessMessage>>(
      std::move(control_fd));
  const int subprocess_fd = control[1];

  std::vector<std::string> child_argv = {fd_arg_ + "=" +
                                         std::to_string(subprocess_fd)};
  const std::vector<std::pair<int, int>> fds_to_bind = {
      {subprocess_fd, subprocess_fd}};

  const auto pid = process_manager_->StartProcess(
      FROM_HERE, cmd_path_, child_argv, /*environment=*/{}, fds_to_bind, true,
      base::BindOnce(&SubprocessController::OnProcessExitedUnexpectedly,
                     weak_factory_.GetWeakPtr()));
  if (pid != net_base::ProcessManager::kInvalidPID) {
    pid_ = pid;
  } else {
    LOG(ERROR) << "Failed to start the subprocess: " << fd_arg_;
  }
}

void SubprocessController::OnProcessExitedUnexpectedly(int exit_status) {
  const auto delay = base::Milliseconds(kSubprocessRestartDelayMs << restarts_);
  LOG(ERROR) << "Subprocess: " << fd_arg_ << " (pid = " << *pid_
             << " ) exited unexpectedly, status: " << exit_status
             << ", attempting to restart after " << delay;

  pid_ = std::nullopt;

  ++restarts_;
  if (restarts_ > kMaxRestarts) {
    LOG(ERROR) << "Subprocess: " << fd_arg_
               << " exceeded maximum number of restarts";
    return;
  }

  // Restart the subprocess with exponential backoff delay.
  base::SingleThreadTaskRunner::GetCurrentDefault()->PostDelayedTask(
      FROM_HERE,
      base::BindOnce(&SubprocessController::Start, weak_factory_.GetWeakPtr()),
      delay);
}

void SubprocessController::SendControlMessage(
    const ControlMessage& proto) const {
  if (!msg_dispatcher_) {
    return;
  }
  SubprocessMessage msg;
  *msg.mutable_control_message() = proto;
  msg_dispatcher_->SendMessage(msg);
}

void SubprocessController::Listen() {
  if (!msg_dispatcher_) {
    return;
  }
  msg_dispatcher_->RegisterMessageHandler(base::BindRepeating(
      &SubprocessController::OnMessage, weak_factory_.GetWeakPtr()));
}

void SubprocessController::RegisterFeedbackMessageHandler(
    base::RepeatingCallback<void(const FeedbackMessage&)> handler) {
  feedback_handler_ = std::move(handler);
}

void SubprocessController::OnMessage(const SubprocessMessage& msg) {
  if (msg.has_feedback_message() && !feedback_handler_.is_null()) {
    feedback_handler_.Run(msg.feedback_message());
  }
}

}  // namespace patchpanel
