//===-- NativeThreadWindows.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 "NativeThreadWindows.h"
#include "NativeProcessWindows.h"

#include "lldb/Host/HostThread.h"
#include "lldb/Host/windows/HostThreadWindows.h"
#include "lldb/Host/windows/LazyImport.h"
#include "lldb/Host/windows/windows.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/State.h"

#include <llvm/Support/ConvertUTF.h>

using namespace lldb;
using namespace lldb_private;

NativeThreadWindows::NativeThreadWindows(NativeProcessWindows &process,
                                         const HostThread &thread)
    : NativeThreadProtocol(process, thread.GetNativeThread().GetThreadId()),
      m_host_thread(thread) {
  m_reg_context_up =
      (NativeRegisterContextWindows::CreateHostNativeRegisterContextWindows(
          process.GetArchitecture(), *this));
}

Status NativeThreadWindows::DoStop() {
  if (m_state != eStateStopped) {
    DWORD previous_suspend_count =
        ::SuspendThread(m_host_thread.GetNativeThread().GetSystemHandle());
    if (previous_suspend_count == static_cast<DWORD>(-1))
      return Status(::GetLastError(), eErrorTypeWin32);

    // Invalidate cached register values on every stop.
    GetRegisterContext().InvalidateAllRegisters();

    m_state = eStateStopped;
  }
  return Status();
}

Status NativeThreadWindows::DoResume(lldb::StateType resume_state) {
  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);
    const ArchSpec &arch = GetProcess().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) {
    // Clear any stop info left over from a previous stop.
    ClearStopInfo();

    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);
    m_state = eStateRunning;
  }

  return Status();
}

std::string NativeThreadWindows::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;
  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;
}

void NativeThreadWindows::SetStopReason(ThreadStopInfo stop_info,
                                        std::string description) {
  m_state = eStateStopped;
  m_stop_info = stop_info;
  m_stop_description = description;
}

bool NativeThreadWindows::GetStopReason(ThreadStopInfo &stop_info,
                                        std::string &description) {
  Log *log = GetLog(LLDBLog::Thread);

  switch (m_state) {
  case eStateStopped:
  case eStateCrashed:
  case eStateExited:
  case eStateSuspended:
  case eStateUnloaded:
    stop_info = m_stop_info;
    description = m_stop_description;
    return true;

  case eStateInvalid:
  case eStateConnected:
  case eStateAttaching:
  case eStateLaunching:
  case eStateRunning:
  case eStateStepping:
  case eStateDetached:
    LLDB_LOGF(log, "tid %" PRIu64 " in state %s cannot answer stop reason",
              GetID(), StateAsCString(m_state));
    return false;
  }
  llvm_unreachable("unhandled StateType!");
}

Status NativeThreadWindows::SetWatchpoint(lldb::addr_t addr, size_t size,
                                          uint32_t watch_flags, bool hardware) {
  if (!hardware)
    return Status::FromErrorString("not implemented");
  if (m_state == eStateLaunching)
    return Status();
  Status error = RemoveWatchpoint(addr);
  if (error.Fail())
    return error;
  uint32_t wp_index =
      m_reg_context_up->SetHardwareWatchpoint(addr, size, watch_flags);
  if (wp_index == LLDB_INVALID_INDEX32)
    return Status::FromErrorString("Setting hardware watchpoint failed.");
  m_watchpoint_index_map.insert({addr, wp_index});
  return Status();
}

Status NativeThreadWindows::RemoveWatchpoint(lldb::addr_t addr) {
  auto wp = m_watchpoint_index_map.find(addr);
  if (wp == m_watchpoint_index_map.end())
    return Status();
  uint32_t wp_index = wp->second;
  m_watchpoint_index_map.erase(wp);
  if (m_reg_context_up->ClearHardwareWatchpoint(wp_index))
    return Status();
  return Status::FromErrorString("Clearing hardware watchpoint failed.");
}

Status NativeThreadWindows::SetHardwareBreakpoint(lldb::addr_t addr,
                                                  size_t size) {
  return Status::FromErrorString("unimplemented.");
}

Status NativeThreadWindows::RemoveHardwareBreakpoint(lldb::addr_t addr) {
  return Status::FromErrorString("unimplemented.");
}
