// Copyright 2018 The Fuchsia 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 "garnet/bin/debug_agent/debugged_job.h"

#include <thread>

#include <lib/fdio/spawn.h>
#include <lib/fit/function.h>
#include <zircon/processargs.h>

#include "garnet/bin/debug_agent/object_util.h"
#include "garnet/lib/debug_ipc/helper/message_loop_zircon.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "lib/fxl/arraysize.h"

namespace debug_agent {

namespace {

class JobDebuggerTest : public ::testing::Test, public ProcessStartHandler {
 public:
  void OnProcessStart(zx::process process) override {
    processes_.push_back(std::move(process));
  }

 protected:
  void SetUp() override {
    message_loop_.Init();
    zx::unowned_job current_job(zx_job_default());
    ASSERT_EQ(ZX_OK, zx::job::create(*current_job, 0u, &job_));
  }

  ~JobDebuggerTest() { message_loop_.Cleanup(); }

  static void LaunchProcess(const zx::job& job,
                            const std::vector<const char*>& argv,
                            const char* name, int outfd, zx_handle_t* proc) {
    std::vector<const char*> normalized_argv = argv;
    normalized_argv.push_back(nullptr);

    // Redirect process's stdout to file.
    fdio_spawn_action_t actions[] = {
        {.action = FDIO_SPAWN_ACTION_CLONE_FD,
         .fd = {.local_fd = outfd, .target_fd = STDOUT_FILENO}},
        {.action = FDIO_SPAWN_ACTION_CLONE_FD,
         .fd = {.local_fd = STDIN_FILENO, .target_fd = STDIN_FILENO}},
        {.action = FDIO_SPAWN_ACTION_CLONE_FD,
         .fd = {.local_fd = STDERR_FILENO, .target_fd = STDERR_FILENO}},
        {.action = FDIO_SPAWN_ACTION_SET_NAME, .name = {.data = name}}};
    char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
    zx_status_t status = fdio_spawn_etc(
        job.get(), FDIO_SPAWN_CLONE_ALL, argv[0], normalized_argv.data(),
        nullptr, arraysize(actions), actions, proc, err_msg);
    ASSERT_EQ(status, ZX_OK) << "Failed to spawn command: " << err_msg;
  }

  // Returns true if condition is true before timeout.
  bool RunLoopWithTimeoutOrUntil(fit::function<bool()> condition,
                                 zx::duration timeout = zx::sec(10),
                                 zx::duration step = zx::msec(10)) {
    const zx::time deadline = (timeout == zx::sec(0))
                                  ? zx::time::infinite()
                                  : zx::deadline_after(timeout);
    while (zx::clock::get_monotonic() < deadline) {
      if (condition()) {
        return true;
      }
      message_loop_.RunUntilTimeout(step);
    }
    return condition();
  }

  void WaitForProcToExit(zx_handle_t proc, int exit_code) {
    zx_info_process_t info;
    ASSERT_TRUE(RunLoopWithTimeoutOrUntil([&] {
      zx_object_get_info(proc, ZX_INFO_PROCESS, &info, sizeof(info), nullptr,
                         nullptr);
      return info.exited;
    }));
    ASSERT_EQ(exit_code, info.return_code);
  }

  std::vector<zx::process> processes_;
  zx::job job_;
  debug_ipc::MessageLoopZircon message_loop_;
};

TEST_F(JobDebuggerTest, OneProcess) {
  zx::job duplicate_job;
  ASSERT_EQ(ZX_OK, job_.duplicate(ZX_RIGHT_SAME_RIGHTS, &duplicate_job));
  DebuggedJob debugged_job(this, KoidForObject(duplicate_job),
                           std::move(duplicate_job));
  ASSERT_TRUE(debugged_job.Init());
  debugged_job.SetFilters({"t"});
  ASSERT_EQ(0u, processes_.size());
  zx_handle_t proc = ZX_HANDLE_INVALID;
  int pipefd[2];
  ASSERT_EQ(0, pipe(pipefd));
  const std::vector<const char*> args = {"/system/bin/true"};
  LaunchProcess(job_, args, "true", pipefd[0], &proc);
  ASSERT_TRUE(RunLoopWithTimeoutOrUntil([this] {
    return processes_.size() == 1;
  })) << "Expected processes size 1, got: "
      << processes_.size();
  zx::process process = zx::process(proc);
  ASSERT_EQ(KoidForObject(processes_[0]), KoidForObject(process));
  WaitForProcToExit(proc, 0);
}

// Tests that job debug exception is removed when debugged job is killed.
TEST_F(JobDebuggerTest, DebuggedJobKilled) {
  // make sure that job debugger works
  {
    zx::job duplicate_job;
    ASSERT_EQ(ZX_OK, job_.duplicate(ZX_RIGHT_SAME_RIGHTS, &duplicate_job));
    DebuggedJob debugged_job(this, KoidForObject(duplicate_job),
                             std::move(duplicate_job));
    ASSERT_TRUE(debugged_job.Init());
    debugged_job.SetFilters({"t"});
    ASSERT_EQ(0u, processes_.size());
    zx_handle_t proc = ZX_HANDLE_INVALID;
    int pipefd[2];
    ASSERT_EQ(0, pipe(pipefd));
    const std::vector<const char*> args = {"/system/bin/true"};
    LaunchProcess(job_, args, "true", pipefd[0], &proc);
    ASSERT_TRUE(RunLoopWithTimeoutOrUntil([this] {
      return processes_.size() == 1;
    })) << "Expected processes size 1, got: "
        << processes_.size();
    zx::process process = zx::process(proc);
    ASSERT_EQ(KoidForObject(processes_[0]), KoidForObject(process));
    WaitForProcToExit(proc, 0);
  }
  // test that new processes are not put into stasis.
  processes_.clear();
  zx_handle_t proc = ZX_HANDLE_INVALID;
  int pipefd[2];
  ASSERT_EQ(0, pipe(pipefd));
  const std::vector<const char*> args = {"/system/bin/true"};
  LaunchProcess(job_, args, "true", pipefd[0], &proc);
  WaitForProcToExit(proc, 0);
  ASSERT_EQ(0u, processes_.size());
}

TEST_F(JobDebuggerTest, MultipleProcesses) {
  zx::job duplicate_job;
  ASSERT_EQ(ZX_OK, job_.duplicate(ZX_RIGHT_SAME_RIGHTS, &duplicate_job));
  DebuggedJob debugged_job(this, KoidForObject(duplicate_job),
                           std::move(duplicate_job));
  ASSERT_TRUE(debugged_job.Init());
  debugged_job.SetFilters({"t"});
  ASSERT_EQ(0u, processes_.size());

  int pipefd[2];
  ASSERT_EQ(0, pipe(pipefd));
  const std::vector<const char*> args = {"/system/bin/true"};
  zx_handle_t proc1 = ZX_HANDLE_INVALID;
  zx_handle_t proc2 = ZX_HANDLE_INVALID;

  LaunchProcess(job_, args, "true", pipefd[0], &proc1);
  zx::process process1 = zx::process(proc1);
  auto pid1 = KoidForObject(process1);

  LaunchProcess(job_, args, "true", pipefd[0], &proc2);
  zx::process process2 = zx::process(proc2);
  auto pid2 = KoidForObject(process2);

  ASSERT_TRUE(RunLoopWithTimeoutOrUntil([this] {
    return processes_.size() == 2;
  })) << "Expected processes size 2, got: "
      << processes_.size();
  std::vector<uint64_t> pids = {KoidForObject(processes_[0]),
                                KoidForObject(processes_[1])};
  EXPECT_THAT(pids, ::testing::UnorderedElementsAre(pid1, pid2));
  WaitForProcToExit(proc1, 0);
  WaitForProcToExit(proc2, 0);
}

TEST_F(JobDebuggerTest, ProcessInNestedJob) {
  zx::job child_job;
  ASSERT_EQ(ZX_OK, zx::job::create(job_, 0u, &child_job));
  zx::job duplicate_job;
  ASSERT_EQ(ZX_OK, job_.duplicate(ZX_RIGHT_SAME_RIGHTS, &duplicate_job));
  DebuggedJob debugged_job(this, KoidForObject(duplicate_job),
                           std::move(duplicate_job));
  ASSERT_TRUE(debugged_job.Init());
  debugged_job.SetFilters({"t"});
  ASSERT_EQ(0u, processes_.size());
  zx_handle_t proc = ZX_HANDLE_INVALID;
  int pipefd[2];
  ASSERT_EQ(0, pipe(pipefd));
  const std::vector<const char*> args = {"/system/bin/true"};
  LaunchProcess(child_job, args, "true", pipefd[0], &proc);
  ASSERT_TRUE(RunLoopWithTimeoutOrUntil([this] {
    return processes_.size() == 1;
  })) << "Expected processes size 1, got: "
      << processes_.size();
  zx::process process = zx::process(proc);
  ASSERT_EQ(KoidForObject(processes_[0]), KoidForObject(process));
  WaitForProcToExit(proc, 0);
}

TEST_F(JobDebuggerTest, FilterFullName) {
  zx::job duplicate_job;
  ASSERT_EQ(ZX_OK, job_.duplicate(ZX_RIGHT_SAME_RIGHTS, &duplicate_job));
  DebuggedJob debugged_job(this, KoidForObject(duplicate_job),
                           std::move(duplicate_job));
  ASSERT_TRUE(debugged_job.Init());
  constexpr char name[] = "true";
  debugged_job.SetFilters({name});
  ASSERT_EQ(0u, processes_.size());
  zx_handle_t proc = ZX_HANDLE_INVALID;
  int pipefd[2];
  ASSERT_EQ(0, pipe(pipefd));
  const std::vector<const char*> args = {"/system/bin/true"};
  LaunchProcess(job_, args, name, pipefd[0], &proc);
  ASSERT_TRUE(RunLoopWithTimeoutOrUntil([this] {
    return processes_.size() == 1;
  })) << "Expected processes size 1, got: "
      << processes_.size();
  zx::process process = zx::process(proc);
  ASSERT_EQ(KoidForObject(processes_[0]), KoidForObject(process));
  WaitForProcToExit(proc, 0);
}

TEST_F(JobDebuggerTest, FilterMultipleProcess) {
  zx::job duplicate_job;
  ASSERT_EQ(ZX_OK, job_.duplicate(ZX_RIGHT_SAME_RIGHTS, &duplicate_job));
  DebuggedJob debugged_job(this, KoidForObject(duplicate_job),
                           std::move(duplicate_job));
  ASSERT_TRUE(debugged_job.Init());
  debugged_job.SetFilters({"t"});
  ASSERT_EQ(0u, processes_.size());

  int pipefd[2];
  ASSERT_EQ(0, pipe(pipefd));
  const std::vector<const char*> args = {"/system/bin/true"};
  zx_handle_t proc1 = ZX_HANDLE_INVALID;
  zx_handle_t proc2 = ZX_HANDLE_INVALID;

  LaunchProcess(job_, args, "false", pipefd[0], &proc1);

  LaunchProcess(job_, args, "true", pipefd[0], &proc2);
  zx::process process = zx::process(proc2);
  auto pid = KoidForObject(process);

  ASSERT_TRUE(RunLoopWithTimeoutOrUntil([this] {
    return processes_.size() == 1;
  })) << "Expected processes size 1, got: "
      << processes_.size();
  ASSERT_EQ(KoidForObject(processes_[0]), pid);
  WaitForProcToExit(proc1, 0);
  WaitForProcToExit(proc2, 0);
}


// Launch two separate processes and check that multiple filters can attach to
// them.
TEST_F(JobDebuggerTest, MultipleFilters) {
  zx::job duplicate_job;
  ASSERT_EQ(ZX_OK, job_.duplicate(ZX_RIGHT_SAME_RIGHTS, &duplicate_job));
  DebuggedJob debugged_job(this, KoidForObject(duplicate_job),
                           std::move(duplicate_job));
  ASSERT_TRUE(debugged_job.Init());
  debugged_job.SetFilters({"t", "f"});
  ASSERT_EQ(0u, processes_.size());

  int pipefd[2];
  ASSERT_EQ(0, pipe(pipefd));
  const std::vector<const char*> args = {"/system/bin/true"};
  zx_handle_t proc1 = ZX_HANDLE_INVALID;
  zx_handle_t proc2 = ZX_HANDLE_INVALID;

  LaunchProcess(job_, args, "false", pipefd[0], &proc1);
  zx::process process1 = zx::process(proc1);
  auto pid1 = KoidForObject(process1);

  LaunchProcess(job_, args, "true", pipefd[0], &proc2);
  zx::process process2 = zx::process(proc2);
  auto pid2 = KoidForObject(process2);

  ASSERT_TRUE(RunLoopWithTimeoutOrUntil([this] {
    return processes_.size() == 2;
  })) << "Expected processes size 2, got: "
      << processes_.size();

  // debug_agent can get processes in any order because LaunchProcess is async
  // so create an array and check that it contains both pids.
  std::vector<uint64_t> pids = {KoidForObject(processes_[1]),
                                KoidForObject(processes_[0])};
  EXPECT_THAT(pids, ::testing::UnorderedElementsAre(pid2, pid1));
  WaitForProcToExit(proc1, 0);
  WaitForProcToExit(proc2, 0);
}

}  // namespace

}  // namespace debug_agent
