//===-- TargetThreadWindows.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/Host/HostInfo.h"
#include "lldb/Host/windows/LazyImport.h"
#include "lldb/Target/Unwind.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"

#include "ProcessWindows.h"
#include "TargetThreadWindows.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include <llvm/Support/ConvertUTF.h>

#if defined(__x86_64__) || defined(_M_AMD64)
#include "x64/RegisterContextWindows_x64.h"
#elif defined(__i386__) || defined(_M_IX86)
#include "x86/RegisterContextWindows_x86.h"
#elif defined(__aarch64__) || defined(_M_ARM64)
#include "arm64/RegisterContextWindows_arm64.h"
#elif defined(__arm__) || defined(_M_ARM)
#include "arm/RegisterContextWindows_arm.h"
#endif

using namespace lldb;
using namespace lldb_private;

TargetThreadWindows::TargetThreadWindows(ProcessWindows &process,
                                         const HostThread &thread)
    : Thread(process, thread.GetNativeThread().GetThreadId()),
      m_host_thread(thread) {}

TargetThreadWindows::~TargetThreadWindows() { DestroyThread(); }

void TargetThreadWindows::RefreshStateAfterStop() {
  ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
  GetRegisterContext()->InvalidateIfNeeded(false);
}

void TargetThreadWindows::WillResume(lldb::StateType resume_state) {}

void TargetThreadWindows::DidStop() {}

RegisterContextSP TargetThreadWindows::GetRegisterContext() {
  if (!m_reg_context_sp)
    m_reg_context_sp = CreateRegisterContextForFrame(nullptr);

  return m_reg_context_sp;
}

RegisterContextSP
TargetThreadWindows::CreateRegisterContextForFrame(StackFrame *frame) {
  RegisterContextSP reg_ctx_sp;
  uint32_t concrete_frame_idx = 0;
  Log *log = GetLog(LLDBLog::Thread);

  if (frame)
    concrete_frame_idx = frame->GetConcreteFrameIndex();

  if (concrete_frame_idx == 0) {
    if (!m_thread_reg_ctx_sp) {
      ArchSpec arch = HostInfo::GetArchitecture();
      switch (arch.GetMachine()) {
      case llvm::Triple::arm:
      case llvm::Triple::thumb:
#if defined(__arm__) || defined(_M_ARM)
        m_thread_reg_ctx_sp.reset(
            new RegisterContextWindows_arm(*this, concrete_frame_idx));
#else
        LLDB_LOG(log, "debugging foreign targets is currently unsupported");
#endif
        break;

      case llvm::Triple::aarch64:
#if defined(__aarch64__) || defined(_M_ARM64)
        m_thread_reg_ctx_sp.reset(
            new RegisterContextWindows_arm64(*this, concrete_frame_idx));
#else
        LLDB_LOG(log, "debugging foreign targets is currently unsupported");
#endif
        break;

      case llvm::Triple::x86:
#if defined(__i386__) || defined(_M_IX86)
        m_thread_reg_ctx_sp.reset(
            new RegisterContextWindows_x86(*this, concrete_frame_idx));
#else
        LLDB_LOG(log, "debugging foreign targets is currently unsupported");
#endif
        break;

      case llvm::Triple::x86_64:
#if defined(__x86_64__) || defined(_M_AMD64)
        m_thread_reg_ctx_sp.reset(
            new RegisterContextWindows_x64(*this, concrete_frame_idx));
#else
        LLDB_LOG(log, "debugging foreign targets is currently unsupported");
#endif
        break;

      default:
        break;
      }
    }
    reg_ctx_sp = m_thread_reg_ctx_sp;
  } else {
    reg_ctx_sp = GetUnwinder().CreateRegisterContextForFrame(frame);
  }

  return reg_ctx_sp;
}

bool TargetThreadWindows::CalculateStopInfo() {
  SetStopInfo(m_stop_info_sp);
  return true;
}

Status TargetThreadWindows::DoResume() {
  StateType resume_state = GetTemporaryResumeState();
  StateType current_state = GetState();
  if (resume_state == current_state)
    return Status();

  if (resume_state == eStateStepping) {
    Log *log = GetLog(LLDBLog::Thread);

    uint32_t flags_index =
        GetRegisterContext()->ConvertRegisterKindToRegisterNumber(
            eRegisterKindGeneric, LLDB_REGNUM_GENERIC_FLAGS);
    uint64_t flags_value =
        GetRegisterContext()->ReadRegisterAsUnsigned(flags_index, 0);
    ProcessSP process = GetProcess();
    const ArchSpec &arch = process->GetTarget().GetArchitecture();
    switch (arch.GetMachine()) {
    case llvm::Triple::x86:
    case llvm::Triple::x86_64:
      flags_value |= 0x100; // Set the trap flag on the CPU
      break;
    case llvm::Triple::aarch64:
    case llvm::Triple::arm:
    case llvm::Triple::thumb:
      flags_value |= 0x200000; // The SS bit in PState
      break;
    default:
      LLDB_LOG(log, "single stepping unsupported on this architecture");
      break;
    }
    GetRegisterContext()->WriteRegisterFromUnsigned(flags_index, flags_value);
  }

  if (resume_state == eStateStepping || resume_state == eStateRunning) {
    DWORD previous_suspend_count = 0;
    HANDLE thread_handle = m_host_thread.GetNativeThread().GetSystemHandle();
    do {
      // ResumeThread returns -1 on error, or the thread's *previous* suspend
      // count on success. This means that the return value is 1 when the thread
      // was restarted. Note that DWORD is an unsigned int, so we need to
      // explicitly compare with -1.
      previous_suspend_count = ::ResumeThread(thread_handle);

      if (previous_suspend_count == static_cast<DWORD>(-1))
        return Status(::GetLastError(), eErrorTypeWin32);

    } while (previous_suspend_count > 1);
  }

  return Status();
}

const char *TargetThreadWindows::GetName() {
  Log *log = GetLog(LLDBLog::Thread);
  static LazyImport<HRESULT(WINAPI *)(HANDLE, PWSTR *)>
      s_get_thread_description{L"Kernel32.dll", "GetThreadDescription"};
  if (!s_get_thread_description)
    return m_name.c_str();
  auto GetThreadDescription = *s_get_thread_description;

  PWSTR pszThreadName;
  if (SUCCEEDED(GetThreadDescription(
          m_host_thread.GetNativeThread().GetSystemHandle(), &pszThreadName))) {
    LLDB_LOGF(log, "GetThreadDescription: %ls", pszThreadName);
    m_name.clear();
    llvm::convertUTF16ToUTF8String(
        llvm::ArrayRef(reinterpret_cast<char *>(pszThreadName),
                       wcslen(pszThreadName) * sizeof(wchar_t)),
        m_name);
    ::LocalFree(pszThreadName);
  }

  return m_name.c_str();
}
