// Copyright 2015 The Chromium 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 "services/native_support/process_controller_impl.h"

#include <errno.h>
#include <signal.h>
#include <sys/types.h>

#include <utility>

#include "base/bind.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/task_runner.h"
#include "base/threading/simple_thread.h"
#include "mojo/services/files/public/interfaces/types.mojom.h"
#include "services/native_support/process_io_redirection.h"

namespace native_support {

namespace {

void WaitForProcess(
    base::Process process,
    scoped_refptr<base::TaskRunner> done_runner,
    const base::Callback<void(mojo::files::Error, int32_t)>& done_callback) {
  int exit_status = 0;
  mojo::files::Error result = process.WaitForExit(&exit_status)
                                  ? mojo::files::Error::OK
                                  : mojo::files::Error::UNKNOWN;
  done_runner->PostTask(
      FROM_HERE,
      base::Bind(done_callback, result, static_cast<int32_t>(exit_status)));
}

void TerminateProcess(base::Process process) {
  if (!process.Terminate(-1, true))
    LOG(ERROR) << "Failed to kill PID " << process.Pid();
}

}  // namespace

ProcessControllerImpl::ProcessControllerImpl(
    scoped_refptr<base::TaskRunner> worker_runner,
    mojo::InterfaceRequest<ProcessController> request,
    base::Process process,
    std::unique_ptr<ProcessIORedirection> process_io_redirection)
    : worker_runner_(worker_runner.Pass()),
      binding_(this, request.Pass()),
      process_(process.Pass()),
      process_io_redirection_(std::move(process_io_redirection)),
      weak_factory_(this) {
  DCHECK(process_.IsValid());
}

ProcessControllerImpl::~ProcessControllerImpl() {
  if (process_.IsValid()) {
    worker_runner_->PostTask(
        FROM_HERE, base::Bind(&TerminateProcess, base::Passed(&process_)));
  }
}

void ProcessControllerImpl::Wait(const WaitCallback& callback) {
  if (!process_.IsValid()) {
    // TODO(vtl): This isn't quite right.
    callback.Run(mojo::files::Error::UNAVAILABLE, 0);
    return;
  }

  worker_runner_->PostTask(
      FROM_HERE, base::Bind(&WaitForProcess, base::Passed(&process_),
                            base::MessageLoop::current()->task_runner(),
                            base::Bind(&ProcessControllerImpl::OnWaitComplete,
                                       weak_factory_.GetWeakPtr(), callback)));
}

void ProcessControllerImpl::Kill(int32_t signal, const KillCallback& callback) {
  callback.Run(KillHelper(signal));
}

void ProcessControllerImpl::OnWaitComplete(const WaitCallback& callback,
                                           mojo::files::Error result,
                                           int32_t exit_status) {
  callback.Run(result, exit_status);
}

mojo::files::Error ProcessControllerImpl::KillHelper(int32_t signal) {
  if (signal < 0)
    return mojo::files::Error::INVALID_ARGUMENT;

  if (!process_.IsValid()) {
    LOG(ERROR) << "Kill() called after Wait()";
    // TODO(vtl): This error code isn't quite right, but "unavailable" (which
    // would also be wrong) is used for a more appropriate purpose below.
    return mojo::files::Error::INVALID_ARGUMENT;
  }

  // |base::HandleType| is just a typedef for |pid_t|.
  pid_t pid = process_.Handle();

  // Note: |kill()| is not interruptible.
  if (kill(pid, static_cast<int>(signal)) == 0)
    return mojo::files::Error::OK;

  switch (errno) {
    case EINVAL:
      return mojo::files::Error::INVALID_ARGUMENT;
    case EPERM:
      return mojo::files::Error::PERMISSION_DENIED;
    case ESRCH:
      return mojo::files::Error::UNAVAILABLE;
    default:
      break;
  }
  return mojo::files::Error::UNKNOWN;
}

}  // namespace native_support
