// 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 <stdio.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/mock_stream_backend.h"
#include "src/developer/debug/debug_agent/integration_tests/so_wrapper.h"
#include "src/developer/debug/ipc/message_reader.h"
#include "src/developer/debug/shared/message_loop_zircon.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 locate Elf symbols after linking.
//
// 1. Launch a process (through RemoteAPI::OnLaunch) control by the debug agent.
//
// 2. Get the module notication (NotifyModules message) for the process launched
//    in (1). We look over the modules for a module (debug_agent_test_so) that
//    was loaded by this newly created process.
//
// 3. Request the symbol tables for the process and look for a particular entry.
//
// 4. Success!

// The exported symbol we're going to ger a symbol for.
const char* kExportedFunctionName = "InsertBreakpointFunction";
const char* kSecondExportedFunctionName = "AnotherFunctionForKicks";

// 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 ElfSymbolStreamBackend : public MockStreamBackend {
 public:
  ElfSymbolStreamBackend(debug_ipc::MessageLoop* loop) : loop_(loop) {}

  uint64_t so_test_base_addr() const { return so_test_base_addr_; }
  const std::string& so_test_build_id() const { return so_test_build_id_; }
  const debug_ipc::SymbolTablesReply& reply() const { return reply_; }

  // 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;
        so_test_build_id_ = module.build_id;
        break;
      }
    }
    loop_->QuitNow();
  }

 private:
  debug_ipc::MessageLoop* loop_;
  uint64_t so_test_base_addr_ = 0;
  std::string so_test_build_id_;
  debug_ipc::SymbolTablesReply reply_;
};

}  // namespace

TEST(ElfSymbol, Lookup) {
  // 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.
    ElfSymbolStreamBackend mock_stream_backend(loop);
    RemoteAPI* remote_api = mock_stream_backend.remote_api();

    // 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)
        << "Expected ZX_OK, Got: " << debug_ipc::ZxStatusToString(launch_reply.status);

    // We run the look 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 request symbol tables for our module.
    debug_ipc::SymbolTablesRequest symbols_request;
    symbols_request.process_koid = launch_reply.process_koid;
    symbols_request.base = mock_stream_backend.so_test_base_addr();
    symbols_request.build_id = mock_stream_backend.so_test_build_id();
    debug_ipc::SymbolTablesReply symbols_reply;
    remote_api->OnSymbolTables(symbols_request, &symbols_reply);

    uint64_t exported_function_value = 0;
    uint64_t second_exported_function_value = 0;

    for (const auto& symbol : symbols_reply.symbols) {
      if (symbol.name == kExportedFunctionName) {
        exported_function_value = symbol.value;
      } else if (symbol.name == kSecondExportedFunctionName) {
        second_exported_function_value = symbol.value;
      }
    }

    // It's not clear what non-flaky things we can test about the value other
    // than this.
    EXPECT_NE(0U, exported_function_value);
    EXPECT_NE(0U, second_exported_function_value);
  }
}

}  // namespace debug_agent
