//===-- ScriptedThread.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 "ScriptedThread.h"
#include "ScriptedFrame.h"

#include "Plugins/Process/Utility/RegisterContextThreadMemory.h"
#include "Plugins/Process/Utility/StopInfoMachException.h"
#include "lldb/Target/OperatingSystem.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/RegisterContext.h"
#include "lldb/Target/StopInfo.h"
#include "lldb/Target/Unwind.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/LLDBLog.h"
#include <memory>
#include <optional>

using namespace lldb;
using namespace lldb_private;

void ScriptedThread::CheckInterpreterAndScriptObject() const {
  lldbassert(m_script_object_sp && "Invalid Script Object.");
  lldbassert(GetInterface() && "Invalid Scripted Thread Interface.");
}

llvm::Expected<std::shared_ptr<ScriptedThread>>
ScriptedThread::Create(ScriptedProcess &process,
                       StructuredData::Generic *script_object) {
  if (!process.IsValid())
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "Invalid scripted process.");

  process.CheckScriptedInterface();

  auto scripted_thread_interface =
      process.GetInterface().CreateScriptedThreadInterface();
  if (!scripted_thread_interface)
    return llvm::createStringError(
        llvm::inconvertibleErrorCode(),
        "Failed to create scripted thread interface.");

  llvm::StringRef thread_class_name;
  if (!script_object) {
    std::optional<std::string> class_name =
        process.GetInterface().GetScriptedThreadPluginName();
    if (!class_name || class_name->empty())
      return llvm::createStringError(
          llvm::inconvertibleErrorCode(),
          "Failed to get scripted thread class name.");
    thread_class_name = *class_name;
  }

  ExecutionContext exe_ctx(process);
  // The legacy thread-spawn path (no script_object) needs to instantiate a
  // *thread* Python class whose name comes from the process plugin, not the
  // process's own class name. Build a thread-specific metadata for that case;
  // when script_object is non-null the class name is unused so we just forward
  // the process's metadata.
  ScriptedMetadata thread_metadata =
      script_object ? process.m_scripted_metadata
                    : ScriptedMetadata(thread_class_name,
                                       process.m_scripted_metadata.GetArgsSP());
  auto obj_or_err = scripted_thread_interface->CreatePluginObject(
      thread_metadata, exe_ctx, script_object);

  if (!obj_or_err) {
    llvm::consumeError(obj_or_err.takeError());
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "Failed to create script object.");
  }

  StructuredData::GenericSP owned_script_object_sp = *obj_or_err;

  if (!owned_script_object_sp->IsValid())
    return llvm::createStringError(llvm::inconvertibleErrorCode(),
                                   "Created script object is invalid.");

  lldb::tid_t tid = scripted_thread_interface->GetThreadID();

  return std::make_shared<ScriptedThread>(process, scripted_thread_interface,
                                          tid, owned_script_object_sp);
}

ScriptedThread::ScriptedThread(ScriptedProcess &process,
                               ScriptedThreadInterfaceSP interface_sp,
                               lldb::tid_t tid,
                               StructuredData::GenericSP script_object_sp)
    : Thread(process, tid), m_scripted_process(process),
      m_scripted_thread_interface_sp(interface_sp),
      m_script_object_sp(script_object_sp) {}

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

const char *ScriptedThread::GetName() {
  CheckInterpreterAndScriptObject();
  std::optional<std::string> thread_name = GetInterface()->GetName();
  if (!thread_name)
    return nullptr;
  return ConstString(*thread_name).AsCString(nullptr);
}

const char *ScriptedThread::GetQueueName() {
  CheckInterpreterAndScriptObject();
  std::optional<std::string> queue_name = GetInterface()->GetQueue();
  if (!queue_name)
    return nullptr;
  return ConstString(*queue_name).AsCString(nullptr);
}

void ScriptedThread::WillResume(StateType resume_state) {}

void ScriptedThread::ClearStackFrames() { Thread::ClearStackFrames(); }

RegisterContextSP ScriptedThread::GetRegisterContext() {
  if (!m_reg_context_sp)
    m_reg_context_sp = CreateRegisterContextForFrame(nullptr);
  return m_reg_context_sp;
}

RegisterContextSP
ScriptedThread::CreateRegisterContextForFrame(StackFrame *frame) {
  const uint32_t concrete_frame_idx =
      frame ? frame->GetConcreteFrameIndex() : 0;

  if (concrete_frame_idx)
    return GetUnwinder().CreateRegisterContextForFrame(frame);

  lldb::RegisterContextSP reg_ctx_sp;
  Status error;

  std::optional<std::string> reg_data = GetInterface()->GetRegisterContext();
  if (!reg_data)
    return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>(
        LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers data.",
        error, LLDBLog::Thread);

  DataBufferSP data_sp(
      std::make_shared<DataBufferHeap>(reg_data->c_str(), reg_data->size()));

  if (!data_sp->GetByteSize())
    return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>(
        LLVM_PRETTY_FUNCTION, "Failed to copy raw registers data.", error,
        LLDBLog::Thread);

  std::shared_ptr<RegisterContextMemory> reg_ctx_memory =
      std::make_shared<RegisterContextMemory>(
          *this, 0, *GetDynamicRegisterInfo(), LLDB_INVALID_ADDRESS);
  if (!reg_ctx_memory)
    return ScriptedInterface::ErrorWithMessage<lldb::RegisterContextSP>(
        LLVM_PRETTY_FUNCTION, "Failed to create a register context.", error,
        LLDBLog::Thread);

  reg_ctx_memory->SetAllRegisterData(data_sp);
  m_reg_context_sp = reg_ctx_memory;

  return m_reg_context_sp;
}

bool ScriptedThread::LoadArtificialStackFrames() {
  StructuredData::ArraySP arr_sp = GetInterface()->GetStackFrames();

  Status error;
  if (!arr_sp)
    return ScriptedInterface::ErrorWithMessage<bool>(
        LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stackframes.",
        error, LLDBLog::Thread);

  size_t arr_size = arr_sp->GetSize();
  if (!arr_size)
    return ScriptedInterface::ErrorWithMessage<bool>(
        LLVM_PRETTY_FUNCTION, "StackFrame array is empty.", error,
        LLDBLog::Thread);

  if (arr_size > std::numeric_limits<uint32_t>::max())
    return ScriptedInterface::ErrorWithMessage<bool>(
        LLVM_PRETTY_FUNCTION,
        llvm::Twine(
            "StackFrame array size (" + llvm::Twine(arr_size) +
            ") is greater than maximum authorized for a StackFrameList.")
            .str(),
        error, LLDBLog::Thread);

  auto create_frame_from_dict =
      [this, arr_sp](size_t idx,
                     uint32_t frame_list_idx) -> llvm::Expected<StackFrameSP> {
    Status error;
    std::optional<StructuredData::Dictionary *> maybe_dict =
        arr_sp->GetItemAtIndexAsDictionary(idx);
    if (!maybe_dict) {
      ScriptedInterface::ErrorWithMessage<bool>(
          LLVM_PRETTY_FUNCTION,
          llvm::Twine(
              "Couldn't get artificial stackframe dictionary at index (" +
              llvm::Twine(idx) + llvm::Twine(") from stackframe array."))
              .str(),
          error, LLDBLog::Thread);
      return error.ToError();
    }
    StructuredData::Dictionary *dict = *maybe_dict;

    lldb::addr_t pc;
    if (!dict->GetValueForKeyAsInteger("pc", pc)) {
      ScriptedInterface::ErrorWithMessage<bool>(
          LLVM_PRETTY_FUNCTION,
          "Couldn't find value for key 'pc' in stackframe dictionary.", error,
          LLDBLog::Thread);
      return error.ToError();
    }

    Address symbol_addr;
    symbol_addr.SetLoadAddress(pc, &this->GetProcess()->GetTarget());

    lldb::addr_t cfa = LLDB_INVALID_ADDRESS;
    bool cfa_is_valid = false;
    const bool artificial = false;
    const bool behaves_like_zeroth_frame = (frame_list_idx == 0);
    SymbolContext sc;
    symbol_addr.CalculateSymbolContext(&sc);

    return std::make_shared<StackFrame>(shared_from_this(), frame_list_idx, idx,
                                        cfa, cfa_is_valid, pc,
                                        StackFrame::Kind::Synthetic, artificial,
                                        behaves_like_zeroth_frame, &sc);
  };

  auto create_frame_from_script_object =
      [this, arr_sp](size_t idx) -> llvm::Expected<StackFrameSP> {
    Status error;
    StructuredData::ObjectSP object_sp = arr_sp->GetItemAtIndex(idx);
    if (!object_sp || !object_sp->GetAsGeneric()) {
      ScriptedInterface::ErrorWithMessage<bool>(
          LLVM_PRETTY_FUNCTION,
          llvm::Twine("Couldn't get artificial stackframe object at index (" +
                      llvm::Twine(idx) +
                      llvm::Twine(") from stackframe array."))
              .str(),
          error, LLDBLog::Thread);
      return error.ToError();
    }

    auto frame_or_error = ScriptedFrame::Create(
        shared_from_this(), GetInterface(), nullptr, object_sp->GetAsGeneric());

    if (!frame_or_error) {
      ScriptedInterface::ErrorWithMessage<bool>(
          LLVM_PRETTY_FUNCTION, toString(frame_or_error.takeError()), error);
      return error.ToError();
    }

    StackFrameSP frame_sp = frame_or_error.get();
    lldbassert(frame_sp && "Couldn't initialize scripted frame.");

    return frame_sp;
  };

  StackFrameListSP frames = GetStackFrameList();
  uint32_t frame_list_idx = 0;

  for (size_t idx = 0; idx < arr_size; idx++) {
    StackFrameSP synth_frame_sp = nullptr;

    auto frame_from_dict_or_err = create_frame_from_dict(idx, frame_list_idx);
    if (!frame_from_dict_or_err) {
      auto frame_from_script_obj_or_err = create_frame_from_script_object(idx);

      if (!frame_from_script_obj_or_err) {
        return ScriptedInterface::ErrorWithMessage<bool>(
            LLVM_PRETTY_FUNCTION,
            llvm::Twine(
                "Couldn't add artificial frame (" + llvm::Twine(idx) +
                llvm::Twine(") to ScriptedThread StackFrameList: ") +
                llvm::toString(frame_from_script_obj_or_err.takeError()))
                .str(),
            error, LLDBLog::Thread);
      } else {
        llvm::consumeError(frame_from_dict_or_err.takeError());
        synth_frame_sp = *frame_from_script_obj_or_err;
      }
    } else {
      synth_frame_sp = *frame_from_dict_or_err;
    }

    if (!frames->SetFrameAtIndex(frame_list_idx, synth_frame_sp))
      return ScriptedInterface::ErrorWithMessage<bool>(
          LLVM_PRETTY_FUNCTION,
          llvm::Twine("Couldn't add frame (" + llvm::Twine(idx) +
                      llvm::Twine(") to ScriptedThread StackFrameList."))
              .str(),
          error, LLDBLog::Thread);
    frame_list_idx++;

    // Synthesize inline frames, mirroring StackFrameList::FetchFramesUpTo().
    frame_list_idx += frames->SynthesizeInlineFrames(
        synth_frame_sp, /*cfa=*/LLDB_INVALID_ADDRESS);
  }

  // Mark the stack as fully unwound so the regular unwinder doesn't try to
  // extend it beyond the artificial frames (e.g. by reading lr/fp from the
  // register context).
  frames->SetAllFramesFetched();

  return true;
}

bool ScriptedThread::CalculateStopInfo() {
  StructuredData::DictionarySP dict_sp = GetInterface()->GetStopReason();

  Status error;
  if (!dict_sp)
    return ScriptedInterface::ErrorWithMessage<bool>(
        LLVM_PRETTY_FUNCTION, "Failed to get scripted thread stop info.", error,
        LLDBLog::Thread);

  // If we're at a BreakpointSite, mark that we stopped there and
  // need to hit the breakpoint when we resume.  This will be cleared
  // if we CreateStopReasonWithBreakpointSiteID.
  if (RegisterContextSP reg_ctx_sp = GetRegisterContext()) {
    addr_t pc = reg_ctx_sp->GetPC();
    ProcessSP proc = GetProcess();
    if (BreakpointSiteSP bp_site_sp =
            proc->GetBreakpointSiteList().FindByAddress(pc))
      if (proc->IsBreakpointSitePhysicallyEnabled(*bp_site_sp))
        SetThreadStoppedAtUnexecutedBP(pc);
  }

  lldb::StopInfoSP stop_info_sp;
  lldb::StopReason stop_reason_type;

  if (!dict_sp->GetValueForKeyAsInteger("type", stop_reason_type))
    return ScriptedInterface::ErrorWithMessage<bool>(
        LLVM_PRETTY_FUNCTION,
        "Couldn't find value for key 'type' in stop reason dictionary.", error,
        LLDBLog::Thread);

  StructuredData::Dictionary *data_dict;
  if (!dict_sp->GetValueForKeyAsDictionary("data", data_dict))
    return ScriptedInterface::ErrorWithMessage<bool>(
        LLVM_PRETTY_FUNCTION,
        "Couldn't find value for key 'data' in stop reason dictionary.", error,
        LLDBLog::Thread);

  switch (stop_reason_type) {
  case lldb::eStopReasonNone:
    return true;
  case lldb::eStopReasonBreakpoint: {
    lldb::break_id_t break_id;
    data_dict->GetValueForKeyAsInteger("break_id", break_id,
                                       LLDB_INVALID_BREAK_ID);
    stop_info_sp =
        StopInfo::CreateStopReasonWithBreakpointSiteID(*this, break_id);
  } break;
  case lldb::eStopReasonSignal: {
    uint32_t signal;
    llvm::StringRef description;
    if (!data_dict->GetValueForKeyAsInteger("signal", signal)) {
        signal = LLDB_INVALID_SIGNAL_NUMBER;
        return false;
    }
    data_dict->GetValueForKeyAsString("desc", description);
    stop_info_sp =
        StopInfo::CreateStopReasonWithSignal(*this, signal, description.data());
  } break;
  case lldb::eStopReasonTrace: {
    stop_info_sp = StopInfo::CreateStopReasonToTrace(*this);
  } break;
  case lldb::eStopReasonException: {
#if defined(__APPLE__)
    StructuredData::Dictionary *mach_exception;
    if (data_dict->GetValueForKeyAsDictionary("mach_exception",
                                              mach_exception)) {
      llvm::StringRef value;
      mach_exception->GetValueForKeyAsString("type", value);
      auto exc_type =
          StopInfoMachException::MachException::ExceptionCode(value.data());

      if (!exc_type)
        return false;

      uint32_t exc_data_size = 0;
      llvm::SmallVector<uint64_t, 3> raw_codes;

      StructuredData::Array *exc_rawcodes;
      mach_exception->GetValueForKeyAsArray("rawCodes", exc_rawcodes);
      if (exc_rawcodes) {
        auto fetch_data = [&raw_codes](StructuredData::Object *obj) {
          if (!obj)
            return false;
          raw_codes.push_back(obj->GetUnsignedIntegerValue());
          return true;
        };

        exc_rawcodes->ForEach(fetch_data);
        exc_data_size = raw_codes.size();
      }

      stop_info_sp = StopInfoMachException::CreateStopReasonWithMachException(
          *this, *exc_type, exc_data_size,
          exc_data_size >= 1 ? raw_codes[0] : 0,
          exc_data_size >= 2 ? raw_codes[1] : 0,
          exc_data_size >= 3 ? raw_codes[2] : 0);

      break;
    }
#endif
    stop_info_sp =
        StopInfo::CreateStopReasonWithException(*this, "EXC_BAD_ACCESS");
  } break;
  default:
    return ScriptedInterface::ErrorWithMessage<bool>(
        LLVM_PRETTY_FUNCTION,
        llvm::Twine("Unsupported stop reason type (" +
                    llvm::Twine(stop_reason_type) + llvm::Twine(")."))
            .str(),
        error, LLDBLog::Thread);
  }

  if (!stop_info_sp)
    return false;

  SetStopInfo(stop_info_sp);
  return true;
}

void ScriptedThread::RefreshStateAfterStop() {
  GetRegisterContext()->InvalidateIfNeeded(/*force=*/false);
  LoadArtificialStackFrames();
}

lldb::ScriptedThreadInterfaceSP ScriptedThread::GetInterface() const {
  return m_scripted_thread_interface_sp;
}

std::shared_ptr<DynamicRegisterInfo> ScriptedThread::GetDynamicRegisterInfo() {
  CheckInterpreterAndScriptObject();

  if (!m_register_info_sp) {
    StructuredData::DictionarySP reg_info = GetInterface()->GetRegisterInfo();

    Status error;
    if (!reg_info)
      return ScriptedInterface::ErrorWithMessage<
          std::shared_ptr<DynamicRegisterInfo>>(
          LLVM_PRETTY_FUNCTION, "Failed to get scripted thread registers info.",
          error, LLDBLog::Thread);

    m_register_info_sp = DynamicRegisterInfo::Create(
        *reg_info, m_scripted_process.GetTarget().GetArchitecture());
  }

  return m_register_info_sp;
}

StructuredData::ObjectSP ScriptedThread::FetchThreadExtendedInfo() {
  CheckInterpreterAndScriptObject();

  Status error;
  StructuredData::ArraySP extended_info_sp = GetInterface()->GetExtendedInfo();

  if (!extended_info_sp || !extended_info_sp->GetSize())
    return ScriptedInterface::ErrorWithMessage<StructuredData::ObjectSP>(
        LLVM_PRETTY_FUNCTION, "No extended information found", error);

  return extended_info_sp;
}
