// 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/zxdb/client/finish_thread_controller.h"
#include "garnet/bin/zxdb/client/process.h"
#include "garnet/bin/zxdb/client/thread.h"
#include "garnet/bin/zxdb/client/thread_controller_test.h"
#include "garnet/bin/zxdb/client/thread_impl_test_support.h"
#include "garnet/bin/zxdb/common/err.h"
#include "gtest/gtest.h"

namespace zxdb {

namespace {

constexpr uint64_t kInitialAddress = 0x12345678;
constexpr uint64_t kInitialBase = 0x1000;
constexpr uint64_t kReturnAddress = 0x34567890;
constexpr uint64_t kReturnBase = 0x1010;

class FinishThreadControllerTest : public ThreadControllerTest {
 public:
  // Creates a break notification with two stack frames using the constants
  // above.
  debug_ipc::NotifyException MakeBreakNotification() {
    debug_ipc::NotifyException n;

    n.process_koid = process()->GetKoid();
    n.type = debug_ipc::NotifyException::Type::kSoftware;
    n.thread.koid = thread()->GetKoid();
    n.thread.state = debug_ipc::ThreadRecord::State::kBlocked;
    n.thread.stack_amount = debug_ipc::ThreadRecord::StackAmount::kMinimal;
    n.thread.frames.emplace_back(kInitialAddress, kInitialBase, kInitialBase);
    n.thread.frames.emplace_back(kReturnAddress, kReturnBase, kReturnBase);

    return n;
  }
};

}  // namespace

TEST_F(FinishThreadControllerTest, Finish) {
  // Notify of thread stop.
  auto break_notification = MakeBreakNotification();
  InjectException(break_notification);

  // Supply three frames for when the thread requests them: the top one (of the
  // stop above), the one we'll return to, and the one before that (so the
  // fingerprint of the one to return to can be computed). This stack value
  // should be larger than above (stack grows downward).
  debug_ipc::ThreadStatusReply expected_reply;
  // Copy previous frames and add to it.
  expected_reply.record = break_notification.thread;
  expected_reply.record.stack_amount =
      debug_ipc::ThreadRecord::StackAmount::kFull;
  expected_reply.record.frames.emplace_back(kReturnAddress, kReturnBase,
                                            kReturnBase);
  mock_remote_api()->set_thread_status_reply(expected_reply);

  const Frame* frame_zero = thread()->GetStack()[0];

  EXPECT_EQ(0, mock_remote_api()->breakpoint_add_count());
  Err out_err;
  thread()->ContinueWith(std::make_unique<FinishThreadController>(
                             FinishThreadController::FromFrame(), frame_zero),
                         [&out_err](const Err& err) {
                           out_err = err;
                           debug_ipc::MessageLoop::Current()->QuitNow();
                         });
  loop().Run();

  TestThreadObserver thread_observer(thread());

  // Finish should have added a temporary breakpoint at the return address.
  // The particulars of this may change with the implementation, but it's worth
  // testing to make sure the breakpoints are all hooked up to the stepping
  // properly.
  ASSERT_EQ(1, mock_remote_api()->breakpoint_add_count());
  ASSERT_EQ(kReturnAddress, mock_remote_api()->last_breakpoint_address());
  ASSERT_EQ(0, mock_remote_api()->breakpoint_remove_count());

  // Simulate a hit of the breakpoint. This stack pointer is too small
  // (indicating a recursive call) so it should not trigger.
  break_notification.thread.frames.clear();
  break_notification.thread.frames.emplace_back(
      kReturnAddress, kInitialBase - 0x100, kInitialBase - 0x100);
  break_notification.hit_breakpoints.emplace_back();
  break_notification.hit_breakpoints[0].breakpoint_id =
      mock_remote_api()->last_breakpoint_id();
  InjectException(break_notification);
  EXPECT_FALSE(thread_observer.got_stopped());

  // Simulate a breakpoint hit with a lower BP. This should trigger a thread
  // stop.
  break_notification.thread.frames[0].sp = kReturnBase;
  break_notification.thread.frames[0].bp = kReturnBase;
  InjectException(break_notification);
  EXPECT_TRUE(thread_observer.got_stopped());
  EXPECT_EQ(1, mock_remote_api()->breakpoint_remove_count());
}

// Tests "finish" at the bottom stack frame. Normally there's a stack frame
// with an IP of 0 below the last "real" stack frame.
TEST_F(FinishThreadControllerTest, BottomStackFrame) {
  // Notify of thread stop. Here we have the 0th frame of the current
  // location, and a null frame.
  auto break_notification = MakeBreakNotification();
  break_notification.thread.frames[1] = debug_ipc::StackFrame(0, 0, 0);
  InjectException(break_notification);

  // The backtrace reply gives the same two frames since that's all there is
  // (the Thread doesn't know until it requests them).
  debug_ipc::ThreadStatusReply expected_reply;
  expected_reply.record = break_notification.thread;
  expected_reply.record.stack_amount =
      debug_ipc::ThreadRecord::StackAmount::kFull;
  mock_remote_api()->set_thread_status_reply(expected_reply);

  Frame* frame_zero = thread()->GetStack()[0];

  EXPECT_EQ(0, mock_remote_api()->breakpoint_add_count());
  Err out_err;
  thread()->ContinueWith(std::make_unique<FinishThreadController>(
                             FinishThreadController::FromFrame(), frame_zero),
                         [&out_err](const Err& err) {
                           out_err = err;
                           debug_ipc::MessageLoop::Current()->QuitNow();
                         });
  loop().Run();

  TestThreadObserver thread_observer(thread());

  // Since the return address is null, we should not have attempted to create
  // a breakpoint, and the thread should have been resumed.
  ASSERT_EQ(0, mock_remote_api()->breakpoint_add_count());
  ASSERT_EQ(1, mock_remote_api()->resume_count());
}

}  // namespace zxdb
