// 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/event_dispatcher.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();
}

void ExternalTask::DestroyLater(EventDispatcher* dispatcher) {
  // Passes ownership of |this| to Destroy.
  dispatcher->PostTask(FROM_HERE, base::Bind(&Destroy, this));
}

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 << ")";
  death_callback_.Run(pid_, exit_status);
  pid_ = 0;
  rpc_task_.reset();
}

// static
void ExternalTask::Destroy(ExternalTask* task) {
  delete task;
}

}  // namespace shill
