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

#include <utility>
#include <vector>

#include <gtest/gtest.h>

#include "src/developer/debug/debug_agent/test_utils.h"

namespace debug_agent {
namespace {

using CallPair = std::pair<zx_koid_t, uint64_t>;
using CallVector = std::vector<CallPair>;

using WPPair = std::pair<zx_koid_t, debug::AddressRange>;
using WPVector = std::vector<WPPair>;

class TestProcessDelegate : public Breakpoint::ProcessDelegate {
 public:
  const CallVector& register_calls() const { return register_calls_; }
  const CallVector& unregister_calls() const { return unregister_calls_; }

  const WPVector& wp_register_calls() const { return wp_register_calls_; }
  const WPVector& wp_unregister_calls() const { return wp_unregister_calls_; }

  void Clear() {
    register_calls_.clear();
    unregister_calls_.clear();
  }

  debug::Status RegisterBreakpoint(Breakpoint*, zx_koid_t process_koid, uint64_t address) override {
    register_calls_.push_back(std::make_pair(process_koid, address));
    return debug::Status();
  }

  void UnregisterBreakpoint(Breakpoint*, zx_koid_t process_koid, uint64_t address) override {
    unregister_calls_.push_back(std::make_pair(process_koid, address));
  }

  debug::Status RegisterWatchpoint(Breakpoint*, zx_koid_t process_koid,
                                   const debug::AddressRange& range) override {
    wp_register_calls_.push_back(std::make_pair(process_koid, range));
    return debug::Status();
  }

  void UnregisterWatchpoint(Breakpoint*, zx_koid_t process_koid,
                            const debug::AddressRange& range) override {
    wp_unregister_calls_.push_back(std::make_pair(process_koid, range));
  }

 private:
  CallVector register_calls_;
  CallVector unregister_calls_;

  WPVector wp_register_calls_;
  WPVector wp_unregister_calls_;
};

debug_ipc::ProcessBreakpointSettings CreateLocation(zx_koid_t process_koid, zx_koid_t thread_koid,
                                                    const debug::AddressRange& address_range) {
  debug_ipc::ProcessBreakpointSettings settings = {};
  settings.id = {.process = process_koid, .thread = thread_koid};
  settings.address_range = address_range;

  return settings;
}

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

TEST(Breakpoint, Registration) {
  TestProcessDelegate delegate;
  Breakpoint bp(&delegate);

  debug_ipc::BreakpointSettings settings;
  settings.id = 1;
  settings.type = debug_ipc::BreakpointType::kSoftware;
  settings.locations.resize(1);

  constexpr zx_koid_t kProcess1 = 1;
  constexpr uint64_t kAddress1 = 0x1234;

  debug_ipc::ProcessBreakpointSettings& pr_settings = settings.locations.back();
  pr_settings.id = {.process = kProcess1, .thread = 0};
  pr_settings.address = kAddress1;

  // Apply the settings.
  ASSERT_TRUE(bp.SetSettings(settings).ok());
  EXPECT_EQ(CallVector({CallPair{kProcess1, kAddress1}}), delegate.register_calls());
  EXPECT_TRUE(delegate.unregister_calls().empty());

  delegate.Clear();

  // Change the settings to move the breakpoint.
  constexpr zx_koid_t kProcess2 = 2;
  constexpr uint64_t kAddress2 = 0x5678;
  pr_settings.id = {.process = kProcess2, .thread = 0};
  pr_settings.address = kAddress2;

  ASSERT_TRUE(bp.SetSettings(settings).ok());
  EXPECT_EQ(CallVector({CallPair{kProcess2, kAddress2}}), delegate.register_calls());
  EXPECT_EQ(CallVector({CallPair{kProcess1, kAddress1}}), delegate.unregister_calls());

  // Add a new location
  delegate.Clear();

  // Add the old breakpoint and a new one
  debug_ipc::ProcessBreakpointSettings old_pr_settings;
  old_pr_settings.id = {.process = kProcess1, .thread = 0};
  old_pr_settings.address = kAddress1;

  constexpr zx_koid_t kProcess3 = 3;
  constexpr uint64_t kAddress3 = 0x9ABC;

  debug_ipc::ProcessBreakpointSettings new_pr_settings;
  new_pr_settings.id = {.process = kProcess3, .thread = 0};
  new_pr_settings.address = kAddress3;

  settings.locations.clear();
  settings.locations.push_back(old_pr_settings);
  settings.locations.push_back(new_pr_settings);

  ASSERT_TRUE(bp.SetSettings(settings).ok());

  EXPECT_EQ(CallVector({{kProcess1, kAddress1}, {kProcess3, kAddress3}}),
            delegate.register_calls());
  EXPECT_EQ(CallVector({{kProcess2, kAddress2}}), delegate.unregister_calls());
}

// The destructor should clear breakpoint locations.
TEST(Breakpoint, Destructor) {
  TestProcessDelegate delegate;
  std::unique_ptr<Breakpoint> bp = std::make_unique<Breakpoint>(&delegate);

  debug_ipc::BreakpointSettings settings;
  settings.id = 1;
  settings.type = debug_ipc::BreakpointType::kSoftware;
  settings.locations.resize(1);

  constexpr zx_koid_t kProcess1 = 1;
  constexpr uint64_t kAddress1 = 0x1234;

  debug_ipc::ProcessBreakpointSettings& pr_settings = settings.locations.back();
  pr_settings.id = {.process = kProcess1, .thread = 0};
  pr_settings.address = kAddress1;

  // Apply the settings.
  ASSERT_TRUE(bp->SetSettings(settings).ok());
  EXPECT_EQ(CallVector({CallPair{kProcess1, kAddress1}}), delegate.register_calls());
  EXPECT_TRUE(delegate.unregister_calls().empty());

  delegate.Clear();

  // Delete the breakpoint to make sure the locations get updated.
  delegate.Clear();
  bp.reset();
  EXPECT_EQ(CallVector({CallPair{kProcess1, kAddress1}}), delegate.unregister_calls());
}

TEST(Breakpoint, HitCount) {
  TestProcessDelegate delegate;
  std::unique_ptr<Breakpoint> bp = std::make_unique<Breakpoint>(&delegate);

  constexpr uint32_t kBreakpointId = 12;
  debug_ipc::BreakpointSettings settings;
  settings.id = kBreakpointId;
  settings.type = debug_ipc::BreakpointType::kSoftware;
  settings.locations.resize(1);

  constexpr zx_koid_t kProcess1 = 1;
  constexpr uint64_t kAddress1 = 0x1234;

  debug_ipc::ProcessBreakpointSettings& pr_settings = settings.locations.back();
  pr_settings.id = {.process = kProcess1, .thread = 0};
  pr_settings.address = kAddress1;

  // Apply the settings.
  ASSERT_TRUE(bp->SetSettings(settings).ok());
  delegate.Clear();

  EXPECT_EQ(kBreakpointId, bp->stats().id);
  EXPECT_EQ(0u, bp->stats().hit_count);

  EXPECT_EQ(Breakpoint::HitResult::kHit, bp->OnHit());
  EXPECT_EQ(kBreakpointId, bp->stats().id);
  EXPECT_EQ(1u, bp->stats().hit_count);
  EXPECT_FALSE(bp->stats().should_delete);

  EXPECT_EQ(Breakpoint::HitResult::kHit, bp->OnHit());
  EXPECT_EQ(kBreakpointId, bp->stats().id);
  EXPECT_EQ(2u, bp->stats().hit_count);
  EXPECT_FALSE(bp->stats().should_delete);
}

TEST(Breakpoint, OneShot) {
  TestProcessDelegate delegate;
  std::unique_ptr<Breakpoint> bp = std::make_unique<Breakpoint>(&delegate);

  constexpr uint32_t kBreakpointId = 12;
  debug_ipc::BreakpointSettings settings;
  settings.id = kBreakpointId;
  settings.type = debug_ipc::BreakpointType::kSoftware;
  settings.one_shot = true;
  settings.locations.resize(1);

  constexpr zx_koid_t kProcess = 1;
  constexpr uint64_t kAddress = 0x1234;

  debug_ipc::ProcessBreakpointSettings& pr_settings = settings.locations.back();
  pr_settings.id = {.process = kProcess, .thread = 0};
  pr_settings.address = kAddress;

  // Apply the settings.
  ASSERT_TRUE(bp->SetSettings(settings).ok());
  delegate.Clear();

  EXPECT_EQ(kBreakpointId, bp->stats().id);
  EXPECT_EQ(0u, bp->stats().hit_count);
  EXPECT_FALSE(bp->stats().should_delete);

  // The hit count and "should delete" flag should be set.
  EXPECT_EQ(Breakpoint::HitResult::kOneShotHit, bp->OnHit());
  EXPECT_EQ(kBreakpointId, bp->stats().id);
  EXPECT_EQ(1u, bp->stats().hit_count);
  EXPECT_TRUE(bp->stats().should_delete);
}

TEST(Breakpoint, WatchpointLocations) {
  TestProcessDelegate process_delegate;
  Breakpoint breakpoint(&process_delegate);

  constexpr zx_koid_t kProcess1Koid = 0x1;
  constexpr zx_koid_t kProcess2Koid = 0x2;
  constexpr debug::AddressRange kProcess1Range = {0x100, 0x200};
  constexpr debug::AddressRange kProcess2Range = {0x400, 0x800};

  debug_ipc::BreakpointSettings settings;
  settings.id = 1;
  settings.locations.push_back(CreateLocation(kProcess1Koid, 0, kProcess1Range));
  settings.locations.push_back(CreateLocation(kProcess2Koid, 0, kProcess2Range));

  settings.type = debug_ipc::BreakpointType::kReadWrite;
  ASSERT_TRUE(breakpoint.SetSettings(settings).ok());

  settings.type = debug_ipc::BreakpointType::kWrite;
  ASSERT_TRUE(breakpoint.SetSettings(settings).ok());

  EXPECT_EQ(
      process_delegate.wp_register_calls(),
      WPVector({WPPair{kProcess1Koid, kProcess1Range}, WPPair{kProcess2Koid, kProcess2Range}}));
  EXPECT_EQ(process_delegate.wp_unregister_calls(), WPVector{});
}

using BPType = debug_ipc::BreakpointType;

TEST(Breakpoint, DoesExceptionApply) {
  EXPECT_TRUE(Breakpoint::DoesExceptionApply(BPType::kSoftware, BPType::kSoftware));
  EXPECT_FALSE(Breakpoint::DoesExceptionApply(BPType::kSoftware, BPType::kHardware));
  EXPECT_FALSE(Breakpoint::DoesExceptionApply(BPType::kSoftware, BPType::kReadWrite));
  EXPECT_FALSE(Breakpoint::DoesExceptionApply(BPType::kSoftware, BPType::kWrite));

  EXPECT_FALSE(Breakpoint::DoesExceptionApply(BPType::kHardware, BPType::kSoftware));
  EXPECT_TRUE(Breakpoint::DoesExceptionApply(BPType::kHardware, BPType::kHardware));
  EXPECT_FALSE(Breakpoint::DoesExceptionApply(BPType::kHardware, BPType::kReadWrite));
  EXPECT_FALSE(Breakpoint::DoesExceptionApply(BPType::kHardware, BPType::kWrite));

  EXPECT_FALSE(Breakpoint::DoesExceptionApply(BPType::kReadWrite, BPType::kSoftware));
  EXPECT_FALSE(Breakpoint::DoesExceptionApply(BPType::kReadWrite, BPType::kHardware));
  EXPECT_TRUE(Breakpoint::DoesExceptionApply(BPType::kReadWrite, BPType::kReadWrite));
  EXPECT_TRUE(Breakpoint::DoesExceptionApply(BPType::kReadWrite, BPType::kWrite));

  EXPECT_FALSE(Breakpoint::DoesExceptionApply(BPType::kWrite, BPType::kSoftware));
  EXPECT_FALSE(Breakpoint::DoesExceptionApply(BPType::kWrite, BPType::kHardware));
  EXPECT_TRUE(Breakpoint::DoesExceptionApply(BPType::kWrite, BPType::kReadWrite));
  EXPECT_TRUE(Breakpoint::DoesExceptionApply(BPType::kWrite, BPType::kWrite));
}

}  // namespace
}  // namespace debug_agent
