// 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.

#include "shill/external_task.h"

#include <memory>
#include <utility>

#include <base/bind.h>
#include <base/bind_helpers.h>

#include "shill/error.h"
#include "shill/process_manager.h"

namespace shill {

using base::FilePath;
using std::map;
using std::string;
using std::vector;

ExternalTask::ExternalTask(
    ControlInterface* control,
    ProcessManager* process_manager,
    const base::WeakPtr<RpcTaskDelegate>& task_delegate,
    const base::Callback<void(pid_t, int)>& death_callback)
    : control_(control),
      process_manager_(process_manager),
      task_delegate_(task_delegate),
      death_callback_(death_callback),
      pid_(0) {
  CHECK(task_delegate_);
}

ExternalTask::~ExternalTask() {
  ExternalTask::Stop();
}

bool ExternalTask::Start(const FilePath& program,
                         const vector<string>& arguments,
                         const map<string, string>& environment,
                         bool terminate_with_parent,
                         Error* error) {
  CHECK(!pid_);
  CHECK(!rpc_task_);

  // Setup full environment variables.
  auto local_rpc_task = std::make_unique<RpcTask>(control_, this);
  map<string, string> env = local_rpc_task->GetEnvironment();
  env.insert(environment.begin(), environment.end());

  pid_t pid = process_manager_->StartProcess(
      FROM_HERE, program, arguments, env, terminate_with_parent,
      base::Bind(&ExternalTask::OnTaskDied, base::Unretained(this)));

  if (pid < 0) {
    Error::PopulateAndLog(
        FROM_HERE, error, Error::kInternalError,
        string("Unable to spawn: ") + program.value().c_str());
    return false;
  }
  pid_ = pid;
  rpc_task_ = std::move(local_rpc_task);
  return true;
}

bool ExternalTask::StartInMinijail(const FilePath& program,
                                   vector<string>* arguments,
                                   const string user,
                                   const string group,
                                   uint64_t mask,
                                   bool inherit_supplementary_groups,
                                   bool close_nonstd_fds,
                                   Error* error) {
  // Checks will fail if Start or StartInMinijailWithRpcIdentifiers has already
  // been called on this object.
  CHECK(!pid_);
  CHECK(!rpc_task_);

  // Passes the connection identifiers on the command line instead of through
  // environment variables.
  auto local_rpc_task = std::make_unique<RpcTask>(control_, this);
  map<string, string> env = local_rpc_task->GetEnvironment();
  map<string, string>::iterator task_service_variable =
      env.find(kRpcTaskServiceVariable);
  map<string, string>::iterator task_path_variable =
      env.find(kRpcTaskPathVariable);
  // Fails without the necessary environment variables.
  if (task_service_variable == env.end() || task_path_variable == env.end()) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kInternalError,
                          string("Invalid environment variables for: ") +
                              program.value().c_str());
    return false;
  }
  arguments->push_back(base::StringPrintf(
      "--shill_task_service=%s", task_service_variable->second.c_str()));
  arguments->push_back(base::StringPrintf("--shill_task_path=%s",
                                          task_path_variable->second.c_str()));

  pid_t pid = process_manager_->StartProcessInMinijail(
      FROM_HERE, program, *arguments, user, group, mask,
      inherit_supplementary_groups, close_nonstd_fds,
      base::Bind(&ExternalTask::OnTaskDied, base::Unretained(this)));

  if (pid < 0) {
    Error::PopulateAndLog(FROM_HERE, error, Error::kInternalError,
                          string("Unable to spawn: ") +
                              program.value().c_str() +
                              string(" in a minijail."));
    return false;
  }
  pid_ = pid;
  rpc_task_ = std::move(local_rpc_task);
  return true;
}

void ExternalTask::Stop() {
  if (pid_) {
    process_manager_->StopProcess(pid_);
    pid_ = 0;
  }
  rpc_task_.reset();
}

void ExternalTask::GetLogin(string* user, string* password) {
  return task_delegate_->GetLogin(user, password);
}

void ExternalTask::Notify(const string& event,
                          const map<string, string>& details) {
  return task_delegate_->Notify(event, details);
}

void ExternalTask::OnTaskDied(int exit_status) {
  CHECK(pid_);
  LOG(INFO) << __func__ << "(" << pid_ << ", " << exit_status << ")";
  pid_t old_pid = pid_;
  pid_ = 0;
  rpc_task_.reset();
  // Since this method has no more non-static member accesses below this call,
  // the death callback is free to destruct this instance.
  death_callback_.Run(old_pid, exit_status);
}

}  // namespace shill
