// 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/zxdb/client/thread_impl.h"

#include <gtest/gtest.h>

#include "src/developer/debug/shared/message_loop.h"
#include "src/developer/debug/zxdb/client/frame.h"
#include "src/developer/debug/zxdb/client/mock_frame.h"
#include "src/developer/debug/zxdb/client/remote_api_test.h"
#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/client/step_thread_controller.h"
#include "src/developer/debug/zxdb/client/test_thread_observer.h"
#include "src/developer/debug/zxdb/client/thread_controller.h"
#include "src/developer/debug/zxdb/common/err.h"
#include "src/developer/debug/zxdb/symbols/input_location.h"

namespace zxdb {

namespace {

class ThreadImplTest : public RemoteAPITest {};

// This ThreadController always responds with "continue".
class ContinueThreadController : public ThreadController {
 public:
  // The parameter is a variable to set when the OnThreadStop() function is called. It must outlive
  // this class.
  explicit ContinueThreadController(bool* got_stop) : got_stop_(got_stop) {}
  ~ContinueThreadController() override = default;

  // ThreadController implementation.
  void InitWithThread(Thread* thread, fit::callback<void(const Err&)> cb) override {
    SetThread(thread);
    cb(Err());
  }
  ContinueOp GetContinueOp() override { return ContinueOp::Continue(); }
  StopOp OnThreadStop(debug_ipc::ExceptionType stop_type,
                      const std::vector<fxl::WeakPtr<Breakpoint>>& hit_breakpoints) override {
    *got_stop_ = true;
    return kContinue;
  }
  const char* GetName() const override { return "Continue"; }

 private:
  bool* got_stop_;
};

// This ThreadController always reports "kUnexpected" for stops.
class UnexpectedThreadController : public ThreadController {
 public:
  explicit UnexpectedThreadController() = default;
  ~UnexpectedThreadController() override = default;

  // ThreadController implementation.
  void InitWithThread(Thread* thread, fit::callback<void(const Err&)> cb) override {
    SetThread(thread);
    cb(Err());
  }
  ContinueOp GetContinueOp() override { return ContinueOp::Continue(); }
  StopOp OnThreadStop(debug_ipc::ExceptionType stop_type,
                      const std::vector<fxl::WeakPtr<Breakpoint>>& hit_breakpoints) override {
    return kUnexpected;
  }
  const char* GetName() const override { return "Unexpected"; }
};

// This ThreadController responds twice with kFuture and then once with kStop.
class FutureThreadController : public ThreadController {
 public:
  explicit FutureThreadController() = default;
  ~FutureThreadController() override = default;

  // ThreadController implementation.
  void InitWithThread(Thread* thread, fit::callback<void(const Err&)> cb) override {
    SetThread(thread);
    cb(Err());
  }
  ContinueOp GetContinueOp() override { return ContinueOp::Continue(); }
  StopOp OnThreadStop(debug_ipc::ExceptionType stop_type,
                      const std::vector<fxl::WeakPtr<Breakpoint>>& hit_breakpoints) override {
    if (futures_remaining_ == 0)
      return kStopDone;

    futures_remaining_--;
    return kFuture;
  }
  const char* GetName() const override { return "Future"; }

 private:
  int futures_remaining_ = 2;
};

}  // namespace

TEST_F(ThreadImplTest, Frames) {
  // Make a process and thread for notifying about.
  constexpr uint64_t kProcessKoid = 1234;
  InjectProcess(kProcessKoid);
  constexpr uint64_t kThreadKoid = 5678;
  Thread* thread = InjectThread(kProcessKoid, kThreadKoid);

  // The thread should be in a running state with no frames.
  EXPECT_TRUE(thread->GetStack().empty());
  EXPECT_FALSE(thread->GetStack().has_all_frames());

  constexpr uint64_t kAddress1 = 0x12345678;
  constexpr uint64_t kStack1 = 0x7890;
  constexpr uint64_t kAddress2 = 0x34567890;
  constexpr uint64_t kStack2 = 0x7800;

  // Notify of thread stop.
  debug_ipc::NotifyException break_notification;
  break_notification.type = debug_ipc::ExceptionType::kSoftwareBreakpoint;
  break_notification.thread.id = {.process = kProcessKoid, .thread = kThreadKoid};
  break_notification.thread.state = debug_ipc::ThreadRecord::State::kBlocked;
  break_notification.thread.frames.emplace_back(kAddress1, kStack1, kStack2);
  InjectException(break_notification);

  // There should be one frame with the address of the stop.
  EXPECT_FALSE(thread->GetStack().has_all_frames());
  const Stack& stack = thread->GetStack();
  ASSERT_EQ(1u, stack.size());
  EXPECT_EQ(kAddress1, stack[0]->GetAddress());
  EXPECT_EQ(kStack1, stack[0]->GetStackPointer());

  // Construct what the full stack will be returned to the thread. The top element should match the
  // one already there.
  debug_ipc::ThreadStatusReply expected_reply;
  expected_reply.record = break_notification.thread;  // Copies existing frame.
  expected_reply.record.stack_amount = debug_ipc::ThreadRecord::StackAmount::kFull;
  expected_reply.record.frames.emplace_back(kAddress2, kStack2, 0);
  mock_remote_api()->set_thread_status_reply(expected_reply);

  // Asynchronously request the frames.
  thread->GetStack().SyncFrames([](const Err&) { debug::MessageLoop::Current()->QuitNow(); });
  loop().Run();

  // The thread should have the new stack we provided.
  EXPECT_TRUE(thread->GetStack().has_all_frames());
  ASSERT_EQ(2u, stack.size());
  EXPECT_EQ(kAddress1, stack[0]->GetAddress());
  EXPECT_EQ(kStack1, stack[0]->GetStackPointer());
  EXPECT_EQ(kAddress2, stack[1]->GetAddress());
  EXPECT_EQ(kStack2, stack[1]->GetStackPointer());

  // Resuming the thread should clear the frames.
  mock_remote_api()->set_resume_quits_loop(true);
  thread->Continue(false);
  EXPECT_EQ(0u, thread->GetStack().size());
  EXPECT_FALSE(thread->GetStack().has_all_frames());
  loop().Run();

  // After resuming we don't actually know what state the thread is in so nothing should change. If
  // we have better thread state notifications in the future, it would be nice if the thread
  // reported itself as running and the stack was cleared at this point.
}

// Tests that general exceptions still run thread controllers. If the exception is at an address
// where the thread controller says "stop", that thread controller should be notified so it can be
// deleted. It doesn't matter what caused the stop if the thread controller thinks its done.
//
// For this exception case, the thread should always stop, even if the controllers say "continue."
TEST_F(ThreadImplTest, ControllersWithGeneralException) {
  constexpr uint64_t kProcessKoid = 1234;
  InjectProcess(kProcessKoid);
  constexpr uint64_t kThreadKoid = 5678;
  Thread* thread = InjectThread(kProcessKoid, kThreadKoid);

  // Notify of thread stop.
  constexpr uint64_t kAddress1 = 0x12345678;
  constexpr uint64_t kStack1 = 0x7890;
  debug_ipc::NotifyException notification;
  notification.type = debug_ipc::ExceptionType::kSoftwareBreakpoint;
  notification.thread.id = {.process = kProcessKoid, .thread = kThreadKoid};
  notification.thread.state = debug_ipc::ThreadRecord::State::kBlocked;
  notification.thread.frames.emplace_back(kAddress1, kStack1);
  InjectException(notification);

  // Set a controller that always says to continue.
  bool got_stop = false;
  thread->ContinueWith(std::make_unique<ContinueThreadController>(&got_stop),
                       [](const Err& err) {});
  EXPECT_FALSE(got_stop);  // Should not have been called.

  // Start watching for thread events starting now.
  TestThreadObserver thread_observer(thread);

  // Notify on thread stop again (this is the same address as above but it doesn't matter).
  notification.type = debug_ipc::ExceptionType::kGeneral;
  InjectException(notification);

  // The controller should have been notified and the thread should have issued a stop notification
  // even though the controller said to continue.
  EXPECT_TRUE(got_stop);
  EXPECT_TRUE(thread_observer.got_stopped());
}

// Tests conditions where thread controllers report unexpected stop types.
TEST_F(ThreadImplTest, ControllersUnexpected) {
  constexpr uint64_t kProcessKoid = 1234;
  InjectProcess(kProcessKoid);
  constexpr uint64_t kThreadKoid = 5678;
  Thread* thread = InjectThread(kProcessKoid, kThreadKoid);

  TestThreadObserver thread_observer(thread);

  // Notify of thread stop.
  constexpr uint64_t kAddress1 = 0x12345678;
  constexpr uint64_t kStack1 = 0x7890;
  debug_ipc::NotifyException notification;
  notification.type = debug_ipc::ExceptionType::kSoftwareBreakpoint;
  notification.thread.id = {.process = kProcessKoid, .thread = kThreadKoid};
  notification.thread.state = debug_ipc::ThreadRecord::State::kBlocked;
  notification.thread.frames.emplace_back(kAddress1, kStack1);
  InjectException(notification);

  // No controllers means the thread should report "stopped".
  EXPECT_TRUE(thread_observer.got_stopped());
  thread_observer.set_got_stopped(false);

  // Add the controller that always reports unexpected.
  thread->ContinueWith(std::make_unique<UnexpectedThreadController>(), [](const Err& err) {});

  // Notify on thread stop again (this is the same address as above but it doesn't matter).
  notification.type = debug_ipc::ExceptionType::kSingleStep;
  InjectException(notification);

  // When all controllers report unexpected, the thread should stop.
  EXPECT_TRUE(thread_observer.got_stopped());
  thread_observer.set_got_stopped(false);

  // Add a continue controller and throw the exception. There should be one controller voting
  // "continue" and one voting "unexpected" which should continue the thread.
  bool continue_got_stop = false;
  thread->ContinueWith(std::make_unique<ContinueThreadController>(&continue_got_stop),
                       [](const Err& err) {});
  InjectException(notification);
  EXPECT_FALSE(thread_observer.got_stopped());
}

// Sends an exception with no stack. Any thread controllers should get deleted.
TEST_F(ThreadImplTest, StopNoStack) {
  constexpr uint64_t kProcessKoid = 1234;
  InjectProcess(kProcessKoid);
  constexpr uint64_t kThreadKoid = 5678;
  Thread* thread = InjectThread(kProcessKoid, kThreadKoid);

  TestThreadObserver thread_observer(thread);

  // Normal thread stop with a location to begin stepping. Then step.
  std::vector<std::unique_ptr<Frame>> frames;
  frames.push_back(std::make_unique<MockFrame>(
      &session(), thread, Location(Location::State::kAddress, 0x7890), 0x1234));
  InjectExceptionWithStack(kProcessKoid, kThreadKoid, debug_ipc::ExceptionType::kSoftwareBreakpoint,
                           std::move(frames), false);
  thread->ContinueWith(std::make_unique<StepThreadController>(StepMode::kInstruction),
                       [](const Err& err) {});

  ThreadImpl* thread_impl = static_cast<ThreadImpl*>(thread);
  EXPECT_FALSE(thread_impl->controllers_.empty());

  // Notify on thread stop with no stack.
  thread_observer.set_got_stopped(false);
  InjectExceptionWithStack(kProcessKoid, kThreadKoid, debug_ipc::ExceptionType::kSoftwareBreakpoint,
                           {}, false);
  thread_observer.set_got_stopped(false);

  // The thread controllers should be gone.
  EXPECT_TRUE(thread_impl->controllers_.empty());
}

TEST_F(ThreadImplTest, JumpTo) {
  constexpr uint64_t kProcessKoid = 1234;
  InjectProcess(kProcessKoid);
  constexpr uint64_t kThreadKoid = 5678;
  Thread* thread = InjectThread(kProcessKoid, kThreadKoid);

  // Notify of thread stop.
  constexpr uint64_t kAddress1 = 0x12345678;
  constexpr uint64_t kStack = 0x7890;
  debug_ipc::NotifyException notification;
  notification.type = debug_ipc::ExceptionType::kSoftwareBreakpoint;
  notification.thread.id = {.process = kProcessKoid, .thread = kThreadKoid};
  notification.thread.state = debug_ipc::ThreadRecord::State::kBlocked;
  notification.thread.frames.emplace_back(kAddress1, kStack);
  InjectException(notification);

  // Canned response for thread status.
  constexpr uint64_t kDestAddress = 0x7828374510a;
  debug_ipc::ThreadStatusReply status;
  status.record = notification.thread;  // Copies existing frame.
  status.record.stack_amount = debug_ipc::ThreadRecord::StackAmount::kFull;
  status.record.frames[0].ip = kDestAddress;
  mock_remote_api()->set_thread_status_reply(status);

  // Do jump.
  bool called = false;
  Err out_err;
  thread->JumpTo(kDestAddress, [&called, &out_err](const Err& err) {
    called = true;
    out_err = err;
    debug::MessageLoop::Current()->QuitNow();
  });
  EXPECT_FALSE(called);

  // The command should have sent a request to write to the IP. There should be a single register
  // with a value of the new address.
  const auto& written = mock_remote_api()->last_write_registers().registers;
  ASSERT_EQ(1u, written.size());
  ASSERT_EQ(sizeof(uint64_t), written[0].data.size());
  EXPECT_EQ(0, memcmp(&kDestAddress, &written[0].data[0], sizeof(uint64_t)));

  // The callback should be asynchronously received.
  loop().Run();
  EXPECT_TRUE(called);
  EXPECT_FALSE(out_err.has_error());

  // The thread should be in the new location.
  EXPECT_EQ(kDestAddress, thread->GetStack()[0]->GetAddress());
}

TEST_F(ThreadImplTest, FutureThreadController) {
  constexpr uint64_t kProcessKoid = 1234;
  InjectProcess(kProcessKoid);
  constexpr uint64_t kThreadKoid = 5678;
  Thread* thread = InjectThread(kProcessKoid, kThreadKoid);

  TestThreadObserver thread_observer(thread);

  // Notify of thread stop.
  constexpr uint64_t kAddress1 = 0x12345678;
  constexpr uint64_t kStack1 = 0x7890;
  debug_ipc::NotifyException notification;
  notification.type = debug_ipc::ExceptionType::kSingleStep;
  notification.thread.id = {.process = kProcessKoid, .thread = kThreadKoid};
  notification.thread.state = debug_ipc::ThreadRecord::State::kBlocked;
  notification.thread.frames.emplace_back(kAddress1, kStack1);
  InjectException(notification);

  thread->ContinueWith(std::make_unique<FutureThreadController>(), [](const Err& err) {});
  thread_observer.set_got_stopped(false);

  // Notify on thread stop (this is the same address as above but it doesn't matter). The thread
  // controller should report "future" and not notify.
  InjectException(notification);
  EXPECT_FALSE(thread_observer.got_stopped());

  // Declare that future stop as complete. This will return another future.
  thread->ResumeFromAsyncThreadController(std::nullopt);
  EXPECT_FALSE(thread_observer.got_stopped());

  // The third time the controller should report stop which should notify.
  thread->ResumeFromAsyncThreadController(std::nullopt);
  EXPECT_TRUE(thread_observer.got_stopped());
}

}  // namespace zxdb
