// 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 <lib/syslog/cpp/macros.h>
#include <zircon/status.h>

#include <gtest/gtest.h>

#include "src/developer/debug/debug_agent/integration_tests/message_loop_wrapper.h"
#include "src/developer/debug/debug_agent/integration_tests/so_wrapper.h"
#include "src/developer/debug/debug_agent/local_stream_backend.h"
#include "src/developer/debug/debug_agent/zircon_system_interface.h"
#include "src/developer/debug/ipc/message_reader.h"
#include "src/developer/debug/shared/logging/logging.h"
#include "src/developer/debug/shared/platform_message_loop.h"
#include "src/developer/debug/shared/zx_status.h"

namespace debug_agent {

namespace {

// This test is an integration test to verify that the debug agent is able to successfully set
// breakpoints to Zircon and get the correct responses. This particular test does the following
// script:
//
// 1. Load a pre-made .so (debug_agent_test_so) and search for a particular exported function. By
//    also getting the loaded base address of the .so, we can get the offset of the function within
//    the module.
//
// 2. Launch a process (through RemoteAPI::OnLaunch) control by the debug agent.
//
// 3. Get the module notication (NotifyModules message) for the process launched in (2). We look
//    over the modules for the same module (debug_agent_test_so) that was loaded by this newly
//    created process. With the base address of this module, we can use the offset calculated in (1)
//    and get the actual loaded address for the exported function within the process.
//
// 4. Set a breakpoint on that address and resume the process. The test program is written such that
//    it will call the searched symbol, so should hit the breakpoint.
//
// 5. Verify that we get a breakpoint exception on that address.
//
// 6. Success!

// The exported symbol we're going to put the breakpoint on.
const char* kExportedFunctionName = "InsertBreakpointFunction";
const char* kExportedFunctionName2 = "InsertBreakpointFunction2";

// The test .so we load in order to search the offset of the exported symbol
// within it.
const char* kTestSo = "debug_agent_test_so.so";

// The test executable the debug agent is going to launch. This is linked with |kTestSo|, meaning
// that the offset within that .so will be valid into the loaded module of this executable.
/* const char* kTestExecutableName = "breakpoint_test_exe"; */
const char* kTestExecutablePath = "/pkg/bin/breakpoint_test_exe";
const char* kModuleToSearch = "libdebug_agent_test_so.so";

class BreakpointStreamBackend : public LocalStreamBackend {
 public:
  BreakpointStreamBackend(debug_ipc::MessageLoop* loop) : loop_(loop) {}

  uint64_t so_test_base_addr() const { return so_test_base_addr_; }

  bool thread_started() const { return thread_started_; }
  bool thread_exited() const { return thread_exited_; }

  bool process_exited() const { return process_exited_; }

  zx_koid_t process_koid() const { return process_koid_; }
  zx_koid_t thread_koid() const { return thread_koid_; }

  const std::vector<debug_ipc::NotifyException>& exceptions() const { return exceptions_; }

  // The messages we're interested in handling ---------------------------------

  // Searches the loaded modules for specific one.
  void HandleNotifyModules(debug_ipc::NotifyModules modules) override {
    for (auto& module : modules.modules) {
      if (module.name == kModuleToSearch) {
        so_test_base_addr_ = module.base;
        break;
      }
    }
    loop_->QuitNow();
  }

  void HandleNotifyThreadStarting(debug_ipc::NotifyThread thread) override {
    ASSERT_FALSE(thread_started_);
    thread_started_ = true;
    loop_->QuitNow();
  }

  // Records the exception given from the debug agent.
  void HandleNotifyException(debug_ipc::NotifyException exception) override {
    exceptions_.push_back(std::move(exception));
    loop_->QuitNow();
  }

  void HandleNotifyThreadExiting(debug_ipc::NotifyThread thread) override {
    ASSERT_FALSE(thread_exited_);
    thread_exited_ = true;

    loop_->QuitNow();
  }

  void HandleNotifyProcessExiting(debug_ipc::NotifyProcessExiting exit) override {
    ASSERT_FALSE(process_exited_);
    process_exited_ = true;

    loop_->QuitNow();
  }

 private:
  debug_ipc::MessageLoop* loop_;
  uint64_t so_test_base_addr_ = 0;

  bool thread_started_ = false;
  bool thread_exited_ = false;

  bool process_exited_ = false;

  zx_koid_t process_koid_ = 0;
  zx_koid_t thread_koid_ = 0;

  std::vector<debug_ipc::NotifyException> exceptions_;
};

}  // namespace

// TODO(fxbug.dev/73422): This test fails, fix and re-enable.
TEST(BreakpointIntegration, DISABLED_SWBreakpoint) {
  // Uncomment for debugging the test.
  // debug_ipc::SetDebugMode(true);

  // We attempt to load the pre-made .so.
  SoWrapper so_wrapper;
  ASSERT_TRUE(so_wrapper.Init(kTestSo)) << "Could not load so " << kTestSo;

  // Obtain the offsets into the .so of the symbols we want.
  uint64_t symbol_offset1 = so_wrapper.GetSymbolOffset(kTestSo, kExportedFunctionName);
  ASSERT_NE(symbol_offset1, 0u);
  uint64_t symbol_offset2 = so_wrapper.GetSymbolOffset(kTestSo, kExportedFunctionName2);
  ASSERT_NE(symbol_offset2, 0u);

  MessageLoopWrapper loop_wrapper;
  {
    auto* loop = loop_wrapper.loop();
    // This stream backend will take care of intercepting the calls from the debug agent.
    BreakpointStreamBackend mock_stream_backend(loop);

    DebugAgent agent(std::make_unique<ZirconSystemInterface>());
    RemoteAPI* remote_api = &agent;

    agent.Connect(&mock_stream_backend.stream());

    // We launch the test binary.
    debug_ipc::LaunchRequest launch_request = {};
    launch_request.argv.push_back(kTestExecutablePath);
    launch_request.inferior_type = debug_ipc::InferiorType::kBinary;
    debug_ipc::LaunchReply launch_reply;
    remote_api->OnLaunch(launch_request, &launch_reply);
    ASSERT_EQ(launch_reply.status, ZX_OK) << "Got: " << zx_status_get_string(launch_reply.status);

    // We run the loop which will stop at the new thread notification.
    loop->Run();

    // We should have only received a thread started notification.
    ASSERT_TRUE(mock_stream_backend.thread_started());
    ASSERT_TRUE(mock_stream_backend.exceptions().empty());
    ASSERT_FALSE(mock_stream_backend.thread_exited());

    // We resume the thread because the new thread will be stopped.
    debug_ipc::ResumeRequest resume_request;
    resume_request.process_koid = mock_stream_backend.process_koid();
    debug_ipc::ResumeReply resume_reply;
    remote_api->OnResume(resume_request, &resume_reply);

    // We run the loop to get the notifications sent by the agent.
    // The stream backend will stop the loop once it has received the modules notification.
    loop->Run();

    // We should have found the correct module by now.
    ASSERT_NE(mock_stream_backend.so_test_base_addr(), 0u);

    DEBUG_LOG(Test) << "Modules found. Adding breakpoint.";

    // We get the offset of the loaded function within the process space.
    uint64_t module_base = mock_stream_backend.so_test_base_addr();
    uint64_t module_function1 = module_base + symbol_offset1;
    uint64_t module_function2 = module_base + symbol_offset2;

    // We add a breakpoint in the functions.
    constexpr uint32_t kBreakpointId = 1234u;
    debug_ipc::AddOrChangeBreakpointRequest breakpoint_request = {};
    breakpoint_request.breakpoint.id = kBreakpointId;
    breakpoint_request.breakpoint.one_shot = false;

    debug_ipc::ProcessBreakpointSettings location1 = {};
    location1.process_koid = launch_reply.process_id;
    location1.address = module_function1;
    breakpoint_request.breakpoint.locations.push_back(location1);
    debug_ipc::ProcessBreakpointSettings location2 = {};
    location2.process_koid = launch_reply.process_id;
    location2.address = module_function2;
    breakpoint_request.breakpoint.locations.push_back(location2);

    debug_ipc::AddOrChangeBreakpointReply breakpoint_reply;
    remote_api->OnAddOrChangeBreakpoint(breakpoint_request, &breakpoint_reply);
    ASSERT_EQ(breakpoint_reply.status, ZX_OK);

    // Resume the process now that the breakpoint is installed.
    DEBUG_LOG(Test) << "Resuming thread.";
    remote_api->OnResume(resume_request, &resume_reply);
    loop->Run();

    // We should have received a breakpoint exception by now.
    ASSERT_EQ(mock_stream_backend.exceptions().size(), 1u);
    debug_ipc::NotifyException exception = mock_stream_backend.exceptions()[0];
    EXPECT_EQ(exception.thread.process_koid, launch_reply.process_id);
    EXPECT_EQ(exception.type, debug_ipc::ExceptionType::kSoftwareBreakpoint);
    ASSERT_EQ(exception.hit_breakpoints.size(), 1u);
    EXPECT_TRUE(exception.other_affected_threads.empty());  // Test has only one thread.

    // Verify that the correct breakpoint was hit.
    auto& breakpoint = exception.hit_breakpoints[0];
    EXPECT_EQ(breakpoint.id, kBreakpointId);
    EXPECT_EQ(breakpoint.hit_count, 1u);
    EXPECT_FALSE(breakpoint.should_delete);

    // Resuming the thread.
    DEBUG_LOG(Test) << "First breakpoint found, resuming thread.";
    remote_api->OnResume(resume_request, &resume_reply);
    loop->Run();

    // We should've received a second breakpoint exception.
    ASSERT_EQ(mock_stream_backend.exceptions().size(), 2u);
    exception = mock_stream_backend.exceptions()[1];
    EXPECT_EQ(exception.thread.process_koid, launch_reply.process_id);
    EXPECT_EQ(exception.type, debug_ipc::ExceptionType::kSoftwareBreakpoint);
    ASSERT_EQ(exception.hit_breakpoints.size(), 1u);

    // Verify that the correct breakpoint was hit.
    breakpoint = exception.hit_breakpoints[0];
    EXPECT_EQ(breakpoint.id, kBreakpointId);
    EXPECT_EQ(breakpoint.hit_count, 2u);
    EXPECT_FALSE(breakpoint.should_delete);

    // Resuming the thread.
    DEBUG_LOG(Test) << "Second breakpoint found, resuming thread.";
    remote_api->OnResume(resume_request, &resume_reply);
    loop->Run();

    // We verify that the thread exited or the process exited.
    ASSERT_TRUE(mock_stream_backend.thread_exited() || mock_stream_backend.process_exited());
  }
}

#if defined(__aarch64__)
// TODO(donosoc): Currently arm64 has a flake over this functionality.
//                One of the objectives of test week is to fix this flake once
//                and for all.
TEST(BreakpointIntegration, DISABLED_HWBreakpoint) {
#else
TEST(BreakpointIntegration, DISABLED_HWBreakpoint) {
#endif

  // We attempt to load the pre-made .so.
  SoWrapper so_wrapper;
  ASSERT_TRUE(so_wrapper.Init(kTestSo)) << "Could not load so " << kTestSo;

  uint64_t symbol_offset = so_wrapper.GetSymbolOffset(kTestSo, kExportedFunctionName);
  ASSERT_NE(symbol_offset, 0u);

  MessageLoopWrapper loop_wrapper;
  {
    auto* loop = loop_wrapper.loop();

    // This stream backend will take care of intercepting the calls from the debug agent.
    BreakpointStreamBackend mock_stream_backend(loop);

    DebugAgent agent(std::make_unique<ZirconSystemInterface>());
    RemoteAPI* remote_api = &agent;

    agent.Connect(&mock_stream_backend.stream());

    DEBUG_LOG(Test) << "Launching binary.";

    // We launch the test binary.
    debug_ipc::LaunchRequest launch_request = {};
    launch_request.inferior_type = debug_ipc::InferiorType::kBinary;
    launch_request.argv.push_back(kTestExecutablePath);
    debug_ipc::LaunchReply launch_reply;
    remote_api->OnLaunch(launch_request, &launch_reply);
    ASSERT_EQ(launch_reply.status, ZX_OK) << "Got: " << zx_status_get_string(launch_reply.status);

    // We run the loop which will stop at the new thread notification.
    loop->Run();

    // We should have only received a thread started notification.
    ASSERT_TRUE(mock_stream_backend.thread_started());
    ASSERT_TRUE(mock_stream_backend.exceptions().empty());
    ASSERT_FALSE(mock_stream_backend.thread_exited());

    // We resume the thread because the new thread will be stopped.
    debug_ipc::ResumeRequest resume_request;
    resume_request.process_koid = mock_stream_backend.process_koid();
    debug_ipc::ResumeReply resume_reply;
    remote_api->OnResume(resume_request, &resume_reply);

    // We run the loop to get the notifications sent by the agent.
    // The stream backend will stop the loop once it has received the modules notification.
    loop->Run();

    // We should have found the correct module by now.
    ASSERT_NE(mock_stream_backend.so_test_base_addr(), 0u);

    // We get the offset of the loaded function within the process space.
    uint64_t module_base = mock_stream_backend.so_test_base_addr();
    uint64_t module_function = module_base + symbol_offset;

    DEBUG_LOG(Test) << "Setting breakpoint at 0x" << std::hex << module_function;

    // We add a breakpoint in that address.
    constexpr uint32_t kBreakpointId = 1234u;
    debug_ipc::ProcessBreakpointSettings location = {};
    location.process_koid = launch_reply.process_id;
    location.address = module_function;

    debug_ipc::AddOrChangeBreakpointRequest breakpoint_request = {};
    breakpoint_request.breakpoint.id = kBreakpointId;
    breakpoint_request.breakpoint.type = debug_ipc::BreakpointType::kHardware;
    breakpoint_request.breakpoint.one_shot = true;
    breakpoint_request.breakpoint.locations.push_back(location);
    debug_ipc::AddOrChangeBreakpointReply breakpoint_reply;
    remote_api->OnAddOrChangeBreakpoint(breakpoint_request, &breakpoint_reply);
    ASSERT_EQ(breakpoint_reply.status, ZX_OK)
        << "Received: " << debug_ipc::ZxStatusToString(breakpoint_reply.status);

    // Resume the process now that the breakpoint is installed.
    remote_api->OnResume(resume_request, &resume_reply);

    // The loop will run until the stream backend receives an exception notification.
    loop->Run();

    DEBUG_LOG(Test) << "Hit breakpoint.";

    // We should have received an exception now.
    ASSERT_EQ(mock_stream_backend.exceptions().size(), 1u);
    debug_ipc::NotifyException exception = mock_stream_backend.exceptions()[0];
    EXPECT_EQ(exception.thread.process_koid, launch_reply.process_id);
    EXPECT_EQ(exception.type, debug_ipc::ExceptionType::kHardwareBreakpoint)
        << "Got: " << debug_ipc::ExceptionTypeToString(exception.type);
    ASSERT_EQ(exception.hit_breakpoints.size(), 1u);

    // Verify that the correct breakpoint was hit.
    auto& breakpoint = exception.hit_breakpoints[0];
    EXPECT_EQ(breakpoint.id, kBreakpointId);
    EXPECT_EQ(breakpoint.hit_count, 1u);
    EXPECT_TRUE(breakpoint.should_delete);

    // Resume the thread again.
    remote_api->OnResume(resume_request, &resume_reply);
    loop->Run();

    DEBUG_LOG(Test) << "Verifyint thread exited correctly.";

    // We verify that the thread exited or the process exited.
    ASSERT_TRUE(mock_stream_backend.thread_exited() || mock_stream_backend.process_exited());
  }
}

}  // namespace debug_agent
