//===-- ThreadTest.cpp ------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Target/Thread.h"
#include "Plugins/Platform/Linux/PlatformLinux.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Host/FileSystem.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Utility/ArchSpec.h"
#include "lldb/Utility/Reproducer.h"
#include "gtest/gtest.h"

using namespace lldb_private;
using namespace lldb_private::repro;
using namespace lldb;

namespace {
class ThreadTest : public ::testing::Test {
public:
  void SetUp() override {
    llvm::cantFail(Reproducer::Initialize(ReproducerMode::Off, llvm::None));
    FileSystem::Initialize();
    HostInfo::Initialize();
    platform_linux::PlatformLinux::Initialize();
  }
  void TearDown() override {
    platform_linux::PlatformLinux::Terminate();
    HostInfo::Terminate();
    FileSystem::Terminate();
    Reproducer::Terminate();
  }
};

class DummyProcess : public Process {
public:
  using Process::Process;

  bool CanDebug(lldb::TargetSP target, bool plugin_specified_by_name) override {
    return true;
  }
  Status DoDestroy() override { return {}; }
  void RefreshStateAfterStop() override {}
  size_t DoReadMemory(lldb::addr_t vm_addr, void *buf, size_t size,
                      Status &error) override {
    return 0;
  }
  bool DoUpdateThreadList(ThreadList &old_thread_list,
                          ThreadList &new_thread_list) override {
    return false;
  }
  ConstString GetPluginName() override { return ConstString("Dummy"); }
  uint32_t GetPluginVersion() override { return 0; }

  ProcessModID &GetModIDNonConstRef() { return m_mod_id; }
};

class DummyThread : public Thread {
public:
  using Thread::Thread;

  ~DummyThread() override { DestroyThread(); }

  void RefreshStateAfterStop() override {}

  lldb::RegisterContextSP GetRegisterContext() override { return nullptr; }

  lldb::RegisterContextSP
  CreateRegisterContextForFrame(StackFrame *frame) override {
    return nullptr;
  }

  bool CalculateStopInfo() override { return false; }

  bool IsStillAtLastBreakpointHit() override { return true; }
};
} // namespace

TargetSP CreateTarget(DebuggerSP &debugger_sp, ArchSpec &arch) {
  PlatformSP platform_sp;
  TargetSP target_sp;
  debugger_sp->GetTargetList().CreateTarget(
      *debugger_sp, "", arch, eLoadDependentsNo, platform_sp, target_sp);

  return target_sp;
}

TEST_F(ThreadTest, SetStopInfo) {
  ArchSpec arch("powerpc64-pc-linux");

  Platform::SetHostPlatform(
      platform_linux::PlatformLinux::CreateInstance(true, &arch));

  DebuggerSP debugger_sp = Debugger::CreateInstance();
  ASSERT_TRUE(debugger_sp);

  TargetSP target_sp = CreateTarget(debugger_sp, arch);
  ASSERT_TRUE(target_sp);

  ListenerSP listener_sp(Listener::MakeListener("dummy"));
  ProcessSP process_sp = std::make_shared<DummyProcess>(target_sp, listener_sp);
  ASSERT_TRUE(process_sp);

  DummyProcess *process = static_cast<DummyProcess *>(process_sp.get());

  ThreadSP thread_sp = std::make_shared<DummyThread>(*process_sp.get(), 0);
  ASSERT_TRUE(thread_sp);

  StopInfoSP stopinfo_sp =
      StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp.get(), 0);
  ASSERT_TRUE(stopinfo_sp->IsValid() == true);

  /*
   Should make stopinfo valid.
   */
  process->GetModIDNonConstRef().BumpStopID();
  ASSERT_TRUE(stopinfo_sp->IsValid() == false);

  thread_sp->SetStopInfo(stopinfo_sp);
  ASSERT_TRUE(stopinfo_sp->IsValid() == true);
}

TEST_F(ThreadTest, GetPrivateStopInfo) {
  ArchSpec arch("powerpc64-pc-linux");

  Platform::SetHostPlatform(
      platform_linux::PlatformLinux::CreateInstance(true, &arch));

  DebuggerSP debugger_sp = Debugger::CreateInstance();
  ASSERT_TRUE(debugger_sp);

  TargetSP target_sp = CreateTarget(debugger_sp, arch);
  ASSERT_TRUE(target_sp);

  ListenerSP listener_sp(Listener::MakeListener("dummy"));
  ProcessSP process_sp = std::make_shared<DummyProcess>(target_sp, listener_sp);
  ASSERT_TRUE(process_sp);

  DummyProcess *process = static_cast<DummyProcess *>(process_sp.get());

  ThreadSP thread_sp = std::make_shared<DummyThread>(*process_sp.get(), 0);
  ASSERT_TRUE(thread_sp);

  StopInfoSP stopinfo_sp =
      StopInfo::CreateStopReasonWithBreakpointSiteID(*thread_sp.get(), 0);
  ASSERT_TRUE(stopinfo_sp);

  thread_sp->SetStopInfo(stopinfo_sp);

  /*
   Should make stopinfo valid if thread is at last breakpoint hit.
   */
  process->GetModIDNonConstRef().BumpStopID();
  ASSERT_TRUE(stopinfo_sp->IsValid() == false);
  StopInfoSP new_stopinfo_sp = thread_sp->GetPrivateStopInfo();
  ASSERT_TRUE(new_stopinfo_sp && stopinfo_sp->IsValid() == true);
}
