// Copyright 2019 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 "src/developer/debug/debug_agent/debug_agent.h"

#include <zircon/status.h>

#include <gtest/gtest.h>

#include "src/developer/debug/debug_agent/arch_provider_impl.h"
#include "src/developer/debug/debug_agent/local_stream_backend.h"
#include "src/developer/debug/debug_agent/mock_object_provider.h"
#include "src/developer/debug/debug_agent/mock_process.h"
#include "src/developer/debug/debug_agent/system_info.h"
#include "src/developer/debug/debug_agent/test_utils.h"
#include "src/developer/debug/ipc/agent_protocol.h"
#include "src/developer/debug/ipc/message_writer.h"
#include "src/developer/debug/shared/platform_message_loop.h"
#include "src/lib/fxl/logging.h"
#include "src/lib/fxl/strings/string_printf.h"

using namespace fuchsia::exception;

namespace debug_agent {
namespace {

// Setup -------------------------------------------------------------------------------------------

class DebugAgentMessageLoop : public debug_ipc::PlatformMessageLoop {
 public:
  DebugAgentMessageLoop() {
    std::string error_message;
    bool success = Init(&error_message);
    FXL_CHECK(success) << error_message;
  }
  ~DebugAgentMessageLoop() { Cleanup(); }

  void StopWatching(int id) override {}

  zx_status_t WatchProcessExceptions(WatchProcessConfig config, WatchHandle* out) override {
    watches_.push_back(std::move(config));
    *out = WatchHandle(this, next_watch_id_++);
    return ZX_OK;
  }

  const std::vector<WatchProcessConfig> watches() const { return watches_; }

 private:
  int next_watch_id_ = 1;

  std::vector<WatchProcessConfig> watches_;
};

class DebugAgentStreamBackend : public LocalStreamBackend {
 public:
  void HandleAttach(debug_ipc::AttachReply attach_reply) override {
    attach_replies_.push_back(std::move(attach_reply));
  }

  void HandleNotifyProcessStarting(debug_ipc::NotifyProcessStarting notification) override {
    process_starts_.push_back(std::move(notification));
  }

  void HandleNotifyModules(debug_ipc::NotifyModules modules) override {
    modules_.push_back(std::move(modules));
  }

  const std::vector<debug_ipc::AttachReply>& attach_replies() const { return attach_replies_; }
  const std::vector<debug_ipc::NotifyProcessStarting>& process_starts() const {
    return process_starts_;
  }
  const std::vector<debug_ipc::NotifyModules> modules() const { return modules_; }

 private:
  std::vector<debug_ipc::AttachReply> attach_replies_;
  std::vector<debug_ipc::NotifyProcessStarting> process_starts_;
  std::vector<debug_ipc::NotifyModules> modules_;
};

class DebugAgentMockProcess : public MockProcess {
 public:
  DebugAgentMockProcess(DebugAgent* debug_agent, zx_koid_t koid, std::string name,
                        std::shared_ptr<ObjectProvider> object_provider,
                        std::shared_ptr<arch::ArchProvider> arch_provider)
      : MockProcess(debug_agent, koid, std::move(name), std::move(arch_provider),
                    std::move(object_provider)) {}

  ~DebugAgentMockProcess() = default;

  void SuspendAndSendModulesIfKnown() override {
    // Send the modules over to the ipc.
    debug_ipc::MessageWriter writer;
    debug_ipc::WriteNotifyModules(modules_to_send_, &writer);
    debug_agent()->stream()->Write(writer.MessageComplete());
  };

  void set_modules_to_send(debug_ipc::NotifyModules m) { modules_to_send_ = std::move(m); }

 private:
  debug_ipc::NotifyModules modules_to_send_;
};

class MockLimboProvider : public LimboProvider {
 public:
  MockLimboProvider() : LimboProvider(nullptr) {}

  const std::map<zx_koid_t, ProcessExceptionMetadata>& Limbo() const override { return limbo_; }
  const std::vector<zx_koid_t> release_calls() const { return release_calls_; }

  bool Valid() const override { return true; }

  zx_status_t RetrieveException(zx_koid_t process_koid,
                                fuchsia::exception::ProcessException* out) override {
    auto it = limbo_.find(process_koid);
    if (it == limbo_.end())
      return ZX_ERR_NOT_FOUND;

    *out = ToProcessException(it->second);

    limbo_.erase(it);
    return ZX_OK;
  }

  void AppendException(const MockProcessObject* process, const MockThreadObject* thread,
                       ExceptionType exception_type) {
    ExceptionInfo info = {};
    info.process_koid = process->koid;
    info.thread_koid = thread->koid;
    info.type = exception_type;

    ProcessExceptionMetadata metadata = {};
    metadata.set_info(std::move(info));
    metadata.set_process(process->GetHandle());
    metadata.set_thread(thread->GetHandle());

    limbo_[process->koid] = std::move(metadata);
  }

  void CallOnEnterLimbo() {
    FXL_DCHECK(on_enter_limbo_);

    std::vector<ProcessExceptionMetadata> processes;
    processes.reserve(limbo_.size());
    for (const auto& [process_koid, metadata] : limbo_) {
      processes.push_back(CopyMetadata(metadata));
    }

    on_enter_limbo_(std::move(processes));
  }

  zx_status_t ReleaseProcess(zx_koid_t process_koid) override {
    release_calls_.push_back(process_koid);

    auto it = limbo_.find(process_koid);
    if (it == limbo_.end())
      return ZX_ERR_NOT_FOUND;

    limbo_.erase(it);
    return ZX_OK;
  }

 private:
  ProcessExceptionMetadata CopyMetadata(const ProcessExceptionMetadata& metadata) {
    ProcessExceptionMetadata exception = {};

    exception.set_info(metadata.info());
    exception.set_process(zx::process(metadata.info().process_koid));
    exception.set_thread(zx::thread(metadata.info().thread_koid));

    return exception;
  }

  ProcessException ToProcessException(const ProcessExceptionMetadata& metadata) {
    ProcessException exception = {};

    exception.set_info(metadata.info());
    exception.set_exception(zx::exception(metadata.info().thread_koid));
    exception.set_process(zx::process(metadata.info().process_koid));
    exception.set_thread(zx::thread(metadata.info().thread_koid));

    return exception;
  }

  std::map<zx_koid_t, ProcessExceptionMetadata> limbo_;
  std::vector<zx_koid_t> release_calls_;
};

std::pair<const MockProcessObject*, const MockThreadObject*> GetProcessThread(
    const MockObjectProvider& object_provider, const std::string& process_name,
    const std::string& thread_name) {
  const MockProcessObject* process = object_provider.ProcessByName(process_name);
  FXL_DCHECK(process);
  const MockThreadObject* thread = process->GetThread(thread_name);
  FXL_DCHECK(thread);

  return {process, thread};
}

struct TestContext {
  DebugAgentMessageLoop loop;
  DebugAgentStreamBackend stream_backend;

  std::shared_ptr<MockObjectProvider> object_provider;
  std::shared_ptr<MockLimboProvider> limbo_provider;
  std::shared_ptr<arch::ArchProvider> arch_provider;
};

SystemProviders ToSystemProviders(const TestContext& context) {
  SystemProviders providers;
  providers.arch_provider = context.arch_provider;
  providers.limbo_provider = context.limbo_provider;
  providers.object_provider = context.object_provider;

  return providers;
}

std::unique_ptr<TestContext> CreateTestContext() {
  auto context = std::make_unique<TestContext>();
  context->arch_provider = std::make_shared<ArchProviderImpl>();
  context->limbo_provider = std::make_shared<MockLimboProvider>();
  context->object_provider = CreateDefaultMockObjectProvider();
  return context;
}

}  // namespace

// Tests -------------------------------------------------------------------------------------------

class DebugAgentTests : public ::testing::Test {};

TEST_F(DebugAgentTests, OnGlobalStatus) {
  auto test_context = CreateTestContext();

  DebugAgent debug_agent(nullptr, ToSystemProviders(*test_context));
  debug_agent.Connect(&test_context->stream_backend.stream());
  RemoteAPI* remote_api = &debug_agent;

  debug_ipc::StatusRequest request = {};

  debug_ipc::StatusReply reply = {};
  remote_api->OnStatus(request, &reply);

  ASSERT_EQ(reply.processes.size(), 0u);

  constexpr uint64_t kProcessKoid1 = 0x1234;
  const std::string kProcessName1 = "process-1";
  constexpr uint64_t kProcess1ThreadKoid1 = 0x1;

  auto process1 =
      std::make_unique<MockProcess>(nullptr, kProcessKoid1, kProcessName1,
                                    test_context->arch_provider, test_context->object_provider);
  process1->AddThread(kProcess1ThreadKoid1);
  debug_agent.InjectProcessForTest(std::move(process1));

  reply = {};
  remote_api->OnStatus(request, &reply);

  ASSERT_EQ(reply.processes.size(), 1u);
  EXPECT_EQ(reply.processes[0].process_koid, kProcessKoid1);
  EXPECT_EQ(reply.processes[0].process_name, kProcessName1);
  ASSERT_EQ(reply.processes[0].threads.size(), 1u);
  EXPECT_EQ(reply.processes[0].threads[0].process_koid, kProcessKoid1);
  EXPECT_EQ(reply.processes[0].threads[0].thread_koid, kProcess1ThreadKoid1);

  constexpr uint64_t kProcessKoid2 = 0x5678;
  const std::string kProcessName2 = "process-2";
  constexpr uint64_t kProcess2ThreadKoid1 = 0x1;
  constexpr uint64_t kProcess2ThreadKoid2 = 0x2;

  auto process2 =
      std::make_unique<MockProcess>(nullptr, kProcessKoid2, kProcessName2,
                                    test_context->arch_provider, test_context->object_provider);
  process2->AddThread(kProcess2ThreadKoid1);
  process2->AddThread(kProcess2ThreadKoid2);
  debug_agent.InjectProcessForTest(std::move(process2));

  reply = {};
  remote_api->OnStatus(request, &reply);

  ASSERT_EQ(reply.processes.size(), 2u);
  EXPECT_EQ(reply.processes[0].process_koid, kProcessKoid1);
  EXPECT_EQ(reply.processes[0].process_name, kProcessName1);
  ASSERT_EQ(reply.processes[0].threads.size(), 1u);
  EXPECT_EQ(reply.processes[0].threads[0].process_koid, kProcessKoid1);
  EXPECT_EQ(reply.processes[0].threads[0].thread_koid, kProcess1ThreadKoid1);

  EXPECT_EQ(reply.processes[1].process_koid, kProcessKoid2);
  EXPECT_EQ(reply.processes[1].process_name, kProcessName2);
  ASSERT_EQ(reply.processes[1].threads.size(), 2u);
  EXPECT_EQ(reply.processes[1].threads[0].process_koid, kProcessKoid2);
  EXPECT_EQ(reply.processes[1].threads[0].thread_koid, kProcess2ThreadKoid1);
  EXPECT_EQ(reply.processes[1].threads[1].process_koid, kProcessKoid2);
  EXPECT_EQ(reply.processes[1].threads[1].thread_koid, kProcess2ThreadKoid2);

  // Set a limbo provider.
  const MockObjectProvider& object_provider = *test_context->object_provider;

  const std::string kLimboProcess1 = "job1-p1";
  const std::string kLimboProcess1Thread = "initial-thread";
  constexpr ExceptionType kLimboException1 = ExceptionType::FATAL_PAGE_FAULT;
  auto [limbo_proc1, limbo_thread1] =
      GetProcessThread(object_provider, kLimboProcess1, kLimboProcess1Thread);

  const std::string kLimboProcess2 = "job121-p2";
  const std::string kLimboProcess2Thread = "second-thread";
  constexpr ExceptionType kLimboException2 = ExceptionType::UNALIGNED_ACCESS;
  auto [limbo_proc2, limbo_thread2] =
      GetProcessThread(object_provider, kLimboProcess2, kLimboProcess2Thread);

  test_context->limbo_provider->AppendException(limbo_proc1, limbo_thread1, kLimboException1);
  test_context->limbo_provider->AppendException(limbo_proc2, limbo_thread2, kLimboException2);

  reply = {};
  remote_api->OnStatus(request, &reply);

  // The attached processes should still be there.
  ASSERT_EQ(reply.processes.size(), 2u);

  // The limbo processes should be there.
  ASSERT_EQ(reply.limbo.size(), 2u);
  EXPECT_EQ(reply.limbo[0].process_koid, limbo_proc1->koid);
  EXPECT_EQ(reply.limbo[0].process_name, limbo_proc1->name);
  ASSERT_EQ(reply.limbo[0].threads.size(), 1u);
  EXPECT_EQ(reply.limbo[0].threads[0].process_koid, limbo_proc1->koid);
  EXPECT_EQ(reply.limbo[0].threads[0].thread_koid, limbo_thread1->koid);
  EXPECT_EQ(reply.limbo[0].threads[0].name, limbo_thread1->name);
  EXPECT_EQ(reply.limbo[0].threads[0].state, debug_ipc::ThreadRecord::State::kBlocked);
  EXPECT_EQ(reply.limbo[0].threads[0].blocked_reason,
            debug_ipc::ThreadRecord::BlockedReason::kException);

  // TODO(donosoc): Add exception type.
}

TEST_F(DebugAgentTests, OnProcessStatus) {
  auto test_context = CreateTestContext();
  DebugAgent debug_agent(nullptr, ToSystemProviders(*test_context));
  debug_agent.Connect(&test_context->stream_backend.stream());
  RemoteAPI* remote_api = &debug_agent;

  constexpr uint64_t kProcessKoid1 = 0x1234;
  std::string kProcessName1 = "process-1";
  auto process1 = std::make_unique<DebugAgentMockProcess>(
      &debug_agent, kProcessKoid1, kProcessName1, test_context->object_provider,
      test_context->arch_provider);
  debug_agent.InjectProcessForTest(std::move(process1));

  constexpr uint64_t kProcessKoid2 = 0x5678;
  std::string kProcessName2 = "process-2";
  auto process2 = std::make_unique<DebugAgentMockProcess>(
      &debug_agent, kProcessKoid2, kProcessName2, test_context->object_provider,
      test_context->arch_provider);
  auto* process2_ptr = process2.get();
  debug_agent.InjectProcessForTest(std::move(process2));

  // Asking for a un-existent process should fail.
  debug_ipc::ProcessStatusRequest request = {};
  request.process_koid = 0xdeadbeef;

  debug_ipc::ProcessStatusReply reply = {};
  remote_api->OnProcessStatus(request, &reply);
  EXPECT_EQ(reply.status, (uint32_t)ZX_ERR_NOT_FOUND) << zx_status_get_string(reply.status);

  debug_ipc::NotifyModules modules_to_send = {};
  modules_to_send.process_koid = kProcessKoid2;
  modules_to_send.modules.push_back({"module-1", 0x1, 0x5, "build-1"});
  modules_to_send.modules.push_back({"module-2", 0x2, 0x7, "build-2"});
  process2_ptr->set_modules_to_send(modules_to_send);

  // Asking for an existent one should send the process and modules notification.
  request.process_koid = kProcessKoid2;
  remote_api->OnProcessStatus(request, &reply);
  EXPECT_EQ(reply.status, (uint32_t)ZX_OK) << zx_status_get_string(reply.status);

  test_context->loop.RunUntilNoTasks();

  auto& process_starts = test_context->stream_backend.process_starts();
  ASSERT_EQ(process_starts.size(), 1u);
  EXPECT_EQ(process_starts[0].koid, kProcessKoid2);
  EXPECT_EQ(process_starts[0].name, kProcessName2);

  auto& modules = test_context->stream_backend.modules();
  ASSERT_EQ(modules.size(), 1u);
  EXPECT_EQ(modules[0].process_koid, kProcessKoid2);

  ASSERT_EQ(modules[0].modules.size(), modules_to_send.modules.size());
  ASSERT_EQ(modules[0].modules[0].name, modules_to_send.modules[0].name);
  ASSERT_EQ(modules[0].modules[0].base, modules_to_send.modules[0].base);
  ASSERT_EQ(modules[0].modules[0].debug_address, modules_to_send.modules[0].debug_address);
  ASSERT_EQ(modules[0].modules[0].build_id, modules_to_send.modules[0].build_id);
  ASSERT_EQ(modules[0].modules[1].name, modules_to_send.modules[1].name);
  ASSERT_EQ(modules[0].modules[1].base, modules_to_send.modules[1].base);
  ASSERT_EQ(modules[0].modules[1].debug_address, modules_to_send.modules[1].debug_address);
  ASSERT_EQ(modules[0].modules[1].build_id, modules_to_send.modules[1].build_id);
}

TEST_F(DebugAgentTests, OnAttachNotFound) {
  uint32_t transaction_id = 1u;

  auto test_context = CreateTestContext();
  DebugAgent debug_agent(nullptr, ToSystemProviders(*test_context));
  debug_agent.Connect(&test_context->stream_backend.stream());
  RemoteAPI* remote_api = &debug_agent;

  debug_ipc::AttachRequest attach_request;
  attach_request.type = debug_ipc::TaskType::kProcess;
  attach_request.koid = -1;

  remote_api->OnAttach(transaction_id++, attach_request);

  {
    // Should've gotten an attach reply.
    auto& attach_replies = test_context->stream_backend.attach_replies();
    ASSERT_EQ(attach_replies.size(), 1u);
    EXPECT_ZX_EQ(attach_replies[0].status, ZX_ERR_NOT_FOUND);

    // There should be no attach watch.
    auto& watches = test_context->loop.watches();
    ASSERT_EQ(watches.size(), 0u);
  }

  auto [proc_object, thread_object] =
      GetProcessThread(*test_context->object_provider, "job11-p1", "second-thread");
  test_context->limbo_provider->AppendException(proc_object, thread_object,
                                                ExceptionType::FATAL_PAGE_FAULT);

  // Even with limbo it should fail.
  remote_api->OnAttach(transaction_id++, attach_request);

  {
    // Should've gotten an attach reply.
    auto& attach_replies = test_context->stream_backend.attach_replies();
    ASSERT_EQ(attach_replies.size(), 2u);
    EXPECT_ZX_EQ(attach_replies[1].status, ZX_ERR_NOT_FOUND);

    // There should be no attach watch.
    auto& watches = test_context->loop.watches();
    ASSERT_EQ(watches.size(), 0u);
  }
}

TEST_F(DebugAgentTests, OnAttach) {
  uint32_t transaction_id = 1u;

  auto test_context = CreateTestContext();
  DebugAgent debug_agent(nullptr, ToSystemProviders(*test_context));
  debug_agent.Connect(&test_context->stream_backend.stream());
  RemoteAPI* remote_api = &debug_agent;

  debug_ipc::AttachRequest attach_request;
  attach_request.type = debug_ipc::TaskType::kProcess;
  attach_request.koid = 11;

  remote_api->OnAttach(transaction_id++, attach_request);

  // We should've received a watch command (which does the low level exception watching).
  auto& watches = test_context->loop.watches();
  ASSERT_EQ(watches.size(), 1u);
  EXPECT_EQ(watches[0].process_name, "job1-p2");
  EXPECT_EQ(watches[0].process_handle, 11u);
  EXPECT_EQ(watches[0].process_koid, 11u);

  // We should've gotten an attach reply.
  auto& attach_replies = test_context->stream_backend.attach_replies();
  auto reply = attach_replies.back();
  ASSERT_EQ(attach_replies.size(), 1u);
  EXPECT_ZX_EQ(reply.status, ZX_OK);
  EXPECT_EQ(reply.koid, 11u);
  EXPECT_EQ(reply.name, "job1-p2");

  // Asking for some invalid process should fail.
  attach_request.koid = 0x231315;  // Some invalid value.
  remote_api->OnAttach(transaction_id++, attach_request);

  // We should've gotten an error reply.
  ASSERT_EQ(attach_replies.size(), 2u);
  reply = attach_replies.back();
  EXPECT_ZX_EQ(reply.status, ZX_ERR_NOT_FOUND);

  // Attaching to a third process should work.
  attach_request.koid = 21u;
  remote_api->OnAttach(transaction_id++, attach_request);

  ASSERT_EQ(attach_replies.size(), 3u);
  reply = attach_replies.back();
  EXPECT_ZX_EQ(reply.status, ZX_OK);
  EXPECT_EQ(reply.koid, 21u);
  EXPECT_EQ(reply.name, "job121-p2");

  // Attaching again to a process should fail.
  remote_api->OnAttach(transaction_id++, attach_request);

  ASSERT_EQ(attach_replies.size(), 4u);
  reply = attach_replies.back();
  EXPECT_ZX_EQ(reply.status, ZX_ERR_ALREADY_BOUND);
}

TEST_F(DebugAgentTests, AttachToLimbo) {
  uint32_t transaction_id = 1u;

  auto test_context = CreateTestContext();
  DebugAgent debug_agent(nullptr, ToSystemProviders(*test_context));
  debug_agent.Connect(&test_context->stream_backend.stream());
  RemoteAPI* remote_api = &debug_agent;

  auto [proc_object, thread_object] =
      GetProcessThread(*test_context->object_provider, "job11-p1", "second-thread");
  test_context->limbo_provider->AppendException(proc_object, thread_object,
                                                ExceptionType::FATAL_PAGE_FAULT);

  debug_ipc::AttachRequest attach_request = {};
  attach_request.type = debug_ipc::TaskType::kProcess;
  attach_request.koid = proc_object->koid;
  remote_api->OnAttach(transaction_id++, attach_request);

  // We should've received a watch command (which does the low level exception watching).
  auto& watches = test_context->loop.watches();
  ASSERT_EQ(watches.size(), 1u);
  EXPECT_EQ(watches[0].process_name, proc_object->name);
  EXPECT_EQ(watches[0].process_handle, proc_object->koid);
  EXPECT_EQ(watches[0].process_koid, proc_object->koid);

  // We should've gotten an attach reply.
  auto& attach_replies = test_context->stream_backend.attach_replies();
  auto reply = attach_replies.back();
  ASSERT_EQ(attach_replies.size(), 1u);
  EXPECT_ZX_EQ(reply.status, ZX_OK);
  EXPECT_EQ(reply.koid, proc_object->koid);
  EXPECT_EQ(reply.name, proc_object->name);

  {
    DebuggedProcess* process = debug_agent.GetDebuggedProcess(proc_object->koid);
    ASSERT_TRUE(process);
    auto threads = process->GetThreads();
    ASSERT_EQ(threads.size(), 2u);

    // Search for the exception thread.
    DebuggedThread* exception_thread = nullptr;
    for (DebuggedThread* thread : threads) {
      if (thread->koid() == thread_object->koid) {
        exception_thread = thread;
        break;
      }
    }

    ASSERT_TRUE(exception_thread);
    ASSERT_TRUE(exception_thread->IsInException());
    EXPECT_EQ(exception_thread->exception_handle().get(), thread_object->koid);
  }
}

TEST_F(DebugAgentTests, OnEnterLimbo) {
  auto test_context = CreateTestContext();
  DebugAgent debug_agent(nullptr, ToSystemProviders(*test_context));
  debug_agent.Connect(&test_context->stream_backend.stream());

  auto [proc_object, thread_object] =
      GetProcessThread(*test_context->object_provider, "job11-p1", "second-thread");
  test_context->limbo_provider->AppendException(proc_object, thread_object,
                                                ExceptionType::FATAL_PAGE_FAULT);

  // Call the limbo.
  test_context->limbo_provider->CallOnEnterLimbo();

  // Should've sent a notification.
  {
    ASSERT_EQ(test_context->stream_backend.process_starts().size(), 1u);

    auto& process_start = test_context->stream_backend.process_starts()[0];
    EXPECT_EQ(process_start.type, debug_ipc::NotifyProcessStarting::Type::kLimbo);
    EXPECT_EQ(process_start.koid, proc_object->koid);
    EXPECT_EQ(process_start.component_id, 0u);
    EXPECT_EQ(process_start.name, proc_object->name);
  }
}

TEST_F(DebugAgentTests, DetachFromLimbo) {
  auto test_context = CreateTestContext();
  DebugAgent debug_agent(nullptr, ToSystemProviders(*test_context));
  debug_agent.Connect(&test_context->stream_backend.stream());
  RemoteAPI* remote_api = &debug_agent;

  auto [proc_object, thread_object] =
      GetProcessThread(*test_context->object_provider, "job11-p1", "second-thread");

  // Attempting to detach to a process that doesn't exist should fail.
  {
    debug_ipc::DetachRequest request = {};
    request.type = debug_ipc::TaskType::kProcess;
    request.koid = proc_object->koid;

    debug_ipc::DetachReply reply = {};
    remote_api->OnDetach(request, &reply);

    ASSERT_ZX_EQ(reply.status, ZX_ERR_NOT_FOUND);
    ASSERT_EQ(test_context->limbo_provider->release_calls().size(), 0u);
  }

  // Adding it should now find it and remove it.
  test_context->limbo_provider->AppendException(proc_object, thread_object,
                                                ExceptionType::FATAL_PAGE_FAULT);
  {
    debug_ipc::DetachRequest request = {};
    request.type = debug_ipc::TaskType::kProcess;
    request.koid = proc_object->koid;

    debug_ipc::DetachReply reply = {};
    remote_api->OnDetach(request, &reply);

    ASSERT_ZX_EQ(reply.status, ZX_OK);
    ASSERT_EQ(test_context->limbo_provider->release_calls().size(), 1u);
    EXPECT_EQ(test_context->limbo_provider->release_calls()[0], proc_object->koid);
  }

  // This should've remove it from limbo, trying it again should fail.
  {
    debug_ipc::DetachRequest request = {};
    request.type = debug_ipc::TaskType::kProcess;
    request.koid = proc_object->koid;

    debug_ipc::DetachReply reply = {};
    remote_api->OnDetach(request, &reply);

    ASSERT_ZX_EQ(reply.status, ZX_ERR_NOT_FOUND);
    ASSERT_EQ(test_context->limbo_provider->release_calls().size(), 1u);
    EXPECT_EQ(test_context->limbo_provider->release_calls()[0], proc_object->koid);
  }
}

TEST_F(DebugAgentTests, Kill) {
  uint32_t transaction_id = 1u;

  auto test_context = CreateTestContext();
  DebugAgent debug_agent(nullptr, ToSystemProviders(*test_context));
  debug_agent.Connect(&test_context->stream_backend.stream());
  RemoteAPI* remote_api = &debug_agent;

  auto [proc_object, thread_object] =
      GetProcessThread(*test_context->object_provider, "job11-p1", "second-thread");

  // Attempt to kill a process that's not there should fail.
  {
    debug_ipc::KillRequest kill_request = {};
    kill_request.process_koid = proc_object->koid;

    debug_ipc::KillReply kill_reply = {};
    remote_api->OnKill(kill_request, &kill_reply);
    ASSERT_ZX_EQ(kill_reply.status, ZX_ERR_NOT_FOUND);
  }

  // Attach to a process so that the debugger knows about it.
  {
    debug_ipc::AttachRequest attach_request = {};
    attach_request.type = debug_ipc::TaskType::kProcess;
    attach_request.koid = proc_object->koid;
    remote_api->OnAttach(transaction_id++, attach_request);

    // There should be a process.
    ASSERT_EQ(debug_agent.procs_.size(), 1u);
  }

  // Killing now should work.
  {
    debug_ipc::KillRequest kill_request = {};
    kill_request.process_koid = proc_object->koid;

    debug_ipc::KillReply kill_reply = {};
    remote_api->OnKill(kill_request, &kill_reply);

    // There should be no more processes.
    ASSERT_EQ(debug_agent.procs_.size(), 0u);

    // Killing again should fail.
    remote_api->OnKill(kill_request, &kill_reply);
    ASSERT_ZX_EQ(kill_reply.status, ZX_ERR_NOT_FOUND);
  }

  // We now add the process to the limbo.
  test_context->limbo_provider->AppendException(proc_object, thread_object,
                                                ExceptionType::FATAL_PAGE_FAULT);

  // There should be no more processes.
  ASSERT_EQ(debug_agent.procs_.size(), 0u);

  // Killing now should release it.
  {
    debug_ipc::KillRequest kill_request = {};
    kill_request.process_koid = proc_object->koid;

    debug_ipc::KillReply kill_reply = {};
    remote_api->OnKill(kill_request, &kill_reply);
    ASSERT_ZX_EQ(kill_reply.status, ZX_OK);

    ASSERT_EQ(test_context->limbo_provider->release_calls().size(), 1u);
    EXPECT_EQ(test_context->limbo_provider->release_calls()[0], proc_object->koid);

    // Killing again should not find it.
    remote_api->OnKill(kill_request, &kill_reply);
    ASSERT_ZX_EQ(kill_reply.status, ZX_ERR_NOT_FOUND);
  }
}

}  // namespace debug_agent
