//===-- ScriptInterpreter.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/Interpreter/ScriptInterpreter.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Host/ConnectionFileDescriptor.h"
#include "lldb/Host/Pipe.h"
#include "lldb/Host/PseudoTerminal.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Stream.h"
#include "lldb/Utility/StringList.h"
#include "lldb/ValueObject/ValueObject.h"
#include "llvm/ADT/StringSwitch.h"
#if defined(_WIN32)
#include "lldb/Host/windows/ConnectionGenericFileWindows.h"
#endif
#include <cstdio>
#include <cstdlib>
#include <memory>
#include <optional>
#include <string>

using namespace lldb;
using namespace lldb_private;

ScriptInterpreter::ScriptInterpreter(Debugger &debugger,
                                     lldb::ScriptLanguage script_lang)
    : m_debugger(debugger), m_script_lang(script_lang) {}

void ScriptInterpreter::CollectDataForBreakpointCommandCallback(
    std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
    CommandReturnObject &result) {
  result.AppendError(
      "This script interpreter does not support breakpoint callbacks.");
}

void ScriptInterpreter::CollectDataForWatchpointCommandCallback(
    WatchpointOptions *bp_options, CommandReturnObject &result) {
  result.AppendError(
      "This script interpreter does not support watchpoint callbacks.");
}

StructuredData::DictionarySP ScriptInterpreter::GetInterpreterInfo() {
  return nullptr;
}

bool ScriptInterpreter::LoadScriptingModule(
    const char *filename, const LoadScriptOptions &options,
    lldb_private::Status &error, StructuredData::ObjectSP *module_sp,
    FileSpec extra_search_dir, lldb::TargetSP loaded_into_target_sp) {
  error = Status::FromErrorString(
      "This script interpreter does not support importing modules.");
  return false;
}

std::string ScriptInterpreter::LanguageToString(lldb::ScriptLanguage language) {
  switch (language) {
  case eScriptLanguageNone:
    return "None";
  case eScriptLanguagePython:
    return "Python";
  case eScriptLanguageLua:
    return "Lua";
  case eScriptLanguageUnknown:
    return "Unknown";
  }
  llvm_unreachable("Unhandled ScriptInterpreter!");
}

lldb::DataExtractorSP
ScriptInterpreter::GetDataExtractorFromSBData(const lldb::SBData &data) const {
  return data.m_opaque_sp;
}

lldb::BreakpointSP ScriptInterpreter::GetOpaqueTypeFromSBBreakpoint(
    const lldb::SBBreakpoint &breakpoint) const {
  return breakpoint.m_opaque_wp.lock();
}

lldb::BreakpointLocationSP
ScriptInterpreter::GetOpaqueTypeFromSBBreakpointLocation(
    const lldb::SBBreakpointLocation &break_loc) const {
  return break_loc.m_opaque_wp.lock();
}

lldb::ProcessAttachInfoSP ScriptInterpreter::GetOpaqueTypeFromSBAttachInfo(
    const lldb::SBAttachInfo &attach_info) const {
  return attach_info.m_opaque_sp;
}

lldb::ProcessLaunchInfoSP ScriptInterpreter::GetOpaqueTypeFromSBLaunchInfo(
    const lldb::SBLaunchInfo &launch_info) const {
  return std::make_shared<ProcessLaunchInfo>(
      *reinterpret_cast<ProcessLaunchInfo *>(launch_info.m_opaque_sp.get()));
}

Status
ScriptInterpreter::GetStatusFromSBError(const lldb::SBError &error) const {
  if (error.m_opaque_up)
    return error.m_opaque_up->Clone();

  return Status();
}

lldb::ThreadSP ScriptInterpreter::GetOpaqueTypeFromSBThread(
    const lldb::SBThread &thread) const {
  if (thread.m_opaque_sp)
    return thread.m_opaque_sp->GetThreadSP();
  return nullptr;
}

lldb::StackFrameSP
ScriptInterpreter::GetOpaqueTypeFromSBFrame(const lldb::SBFrame &frame) const {
  if (frame.m_opaque_sp)
    return frame.m_opaque_sp->GetFrameSP();
  return nullptr;
}

Event *
ScriptInterpreter::GetOpaqueTypeFromSBEvent(const lldb::SBEvent &event) const {
  return event.m_opaque_ptr;
}

lldb::StreamSP ScriptInterpreter::GetOpaqueTypeFromSBStream(
    const lldb::SBStream &stream) const {
  if (stream.m_opaque_up) {
    lldb::StreamSP s = std::make_shared<lldb_private::StreamString>();
    *s << reinterpret_cast<StreamString *>(stream.m_opaque_up.get())->m_packet;
    return s;
  }

  return nullptr;
}

SymbolContext ScriptInterpreter::GetOpaqueTypeFromSBSymbolContext(
    const lldb::SBSymbolContext &sb_sym_ctx) const {
  if (sb_sym_ctx.m_opaque_up)
    return *sb_sym_ctx.m_opaque_up;
  return {};
}

std::optional<lldb_private::MemoryRegionInfo>
ScriptInterpreter::GetOpaqueTypeFromSBMemoryRegionInfo(
    const lldb::SBMemoryRegionInfo &mem_region) const {
  if (!mem_region.m_opaque_up)
    return std::nullopt;
  return *mem_region.m_opaque_up.get();
}

lldb::ExecutionContextRefSP
ScriptInterpreter::GetOpaqueTypeFromSBExecutionContext(
    const lldb::SBExecutionContext &exe_ctx) const {
  return exe_ctx.m_exe_ctx_sp;
}

lldb::StackFrameListSP ScriptInterpreter::GetOpaqueTypeFromSBFrameList(
    const lldb::SBFrameList &frame_list) const {
  return frame_list.m_opaque_sp;
}

lldb::TargetSP ScriptInterpreter::GetOpaqueTypeFromSBTarget(
    const lldb::SBTarget &target) const {
  return target.m_opaque_sp;
}

lldb::ValueObjectSP
ScriptInterpreter::GetOpaqueTypeFromSBValue(const lldb::SBValue &value) const {
  if (!value.m_opaque_sp)
    return lldb::ValueObjectSP();

  lldb_private::ValueLocker locker;
  return locker.GetLockedSP(*value.m_opaque_sp);
}

lldb::ScriptLanguage
ScriptInterpreter::StringToLanguage(const llvm::StringRef &language) {
  if (language.equals_insensitive(LanguageToString(eScriptLanguageNone)))
    return eScriptLanguageNone;
  if (language.equals_insensitive(LanguageToString(eScriptLanguagePython)))
    return eScriptLanguagePython;
  if (language.equals_insensitive(LanguageToString(eScriptLanguageLua)))
    return eScriptLanguageLua;
  return eScriptLanguageUnknown;
}

llvm::StringLiteral
ScriptInterpreter::ExtensionToString(lldb::ScriptedExtension extension) {
  switch (extension) {
  case eScriptedExtensionInvalid:
    return "Invalid";
  case eScriptedExtensionOperatingSystem:
    return "OperatingSystem";
  case eScriptedExtensionScriptedPlatform:
    return "ScriptedPlatform";
  case eScriptedExtensionScriptedProcess:
    return "ScriptedProcess";
  case eScriptedExtensionScriptedBreakpointResolver:
    return "ScriptedBreakpointResolver";
  case eScriptedExtensionScriptedThreadPlan:
    return "ScriptedThreadPlan";
  case eScriptedExtensionScriptedFrameProvider:
    return "ScriptedFrameProvider";
  case eScriptedExtensionScriptedHook:
    return "ScriptedHook";
  case eScriptedExtensionScriptedThread:
    return "ScriptedThread";
  case eScriptedExtensionScriptedFrame:
    return "ScriptedFrame";
  case eScriptedExtensionScriptedStackFrameRecognizer:
    return "ScriptedStackFrameRecognizer";
  }
  llvm_unreachable("unhandled ScriptedExtension");
}

lldb::ScriptedExtension
ScriptInterpreter::StringToExtension(llvm::StringRef string) {
  return llvm::StringSwitch<lldb::ScriptedExtension>(string)
      .CaseLower("OperatingSystem", eScriptedExtensionOperatingSystem)
      .CaseLower("ScriptedPlatform", eScriptedExtensionScriptedPlatform)
      .CaseLower("ScriptedProcess", eScriptedExtensionScriptedProcess)
      .CaseLower("ScriptedBreakpointResolver",
                 eScriptedExtensionScriptedBreakpointResolver)
      .CaseLower("ScriptedThreadPlan", eScriptedExtensionScriptedThreadPlan)
      .CaseLower("ScriptedFrameProvider",
                 eScriptedExtensionScriptedFrameProvider)
      .CaseLower("ScriptedHook", eScriptedExtensionScriptedHook)
      .CaseLower("ScriptedThread", eScriptedExtensionScriptedThread)
      .CaseLower("ScriptedFrame", eScriptedExtensionScriptedFrame)
      .CaseLower("ScriptedStackFrameRecognizer",
                 eScriptedExtensionScriptedStackFrameRecognizer)
      .Default(eScriptedExtensionInvalid);
}

Status ScriptInterpreter::SetBreakpointCommandCallback(
    std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
    const char *callback_text) {
  Status error;
  for (BreakpointOptions &bp_options : bp_options_vec) {
    error = SetBreakpointCommandCallback(bp_options, callback_text,
                                         /*is_callback=*/false);
    if (!error.Success())
      break;
  }
  return error;
}

Status ScriptInterpreter::SetBreakpointCommandCallbackFunction(
    std::vector<std::reference_wrapper<BreakpointOptions>> &bp_options_vec,
    const char *function_name, StructuredData::ObjectSP extra_args_sp) {
  Status error;
  for (BreakpointOptions &bp_options : bp_options_vec) {
    error = SetBreakpointCommandCallbackFunction(bp_options, function_name,
                                                 extra_args_sp);
    if (!error.Success())
      return error;
  }
  return error;
}

std::unique_ptr<ScriptInterpreterLocker>
ScriptInterpreter::AcquireInterpreterLock() {
  return std::make_unique<ScriptInterpreterLocker>();
}

ScriptInterpreter::SanitizedScriptingModuleName
ScriptInterpreter::GetSanitizedScriptingModuleName(llvm::StringRef name) {
  std::string sanitized_name(name);
  std::string conflicting_keyword;

  // FIXME: for Python, don't allow certain characters in imported module
  // filenames. Theoretically, different scripting languages may have
  // different sets of forbidden tokens in filenames, and that should
  // be dealt with by each ScriptInterpreter. For now, just replace dots
  // with underscores. In order to support anything other than Python
  // this will need to be reworked.
  llvm::replace(sanitized_name, '.', '_');
  llvm::replace(sanitized_name, ' ', '_');
  llvm::replace(sanitized_name, '-', '_');
  llvm::replace(sanitized_name, '+', 'x');

  if (IsReservedWord(sanitized_name.c_str())) {
    conflicting_keyword = sanitized_name;
    sanitized_name.insert(sanitized_name.begin(), '_');
  }

  return ScriptInterpreter::SanitizedScriptingModuleName(
      name.str(), std::move(sanitized_name), std::move(conflicting_keyword));
}

static void ReadThreadBytesReceived(void *baton, const void *src,
                                    size_t src_len) {
  if (src && src_len) {
    Stream *strm = (Stream *)baton;
    strm->Write(src, src_len);
    strm->Flush();
  }
}

llvm::Expected<std::unique_ptr<ScriptInterpreterIORedirect>>
ScriptInterpreterIORedirect::Create(bool enable_io, Debugger &debugger,
                                    CommandReturnObject *result) {
  if (enable_io)
    return std::unique_ptr<ScriptInterpreterIORedirect>(
        new ScriptInterpreterIORedirect(debugger, result));

  auto nullin = FileSystem::Instance().Open(FileSpec(FileSystem::DEV_NULL),
                                            File::eOpenOptionReadOnly);
  if (!nullin)
    return nullin.takeError();

  auto nullout = FileSystem::Instance().Open(FileSpec(FileSystem::DEV_NULL),
                                             File::eOpenOptionWriteOnly);
  if (!nullout)
    return nullout.takeError();

  return std::unique_ptr<ScriptInterpreterIORedirect>(
      new ScriptInterpreterIORedirect(std::move(*nullin), std::move(*nullout)));
}

ScriptInterpreterIORedirect::ScriptInterpreterIORedirect(
    std::unique_ptr<File> input, std::unique_ptr<File> output)
    : m_input_file_sp(std::move(input)),
      m_output_file_sp(std::make_shared<LockableStreamFile>(std::move(output),
                                                            m_output_mutex)),
      m_error_file_sp(m_output_file_sp),
      m_communication("lldb.ScriptInterpreterIORedirect.comm"),
      m_disconnect(false) {}

ScriptInterpreterIORedirect::ScriptInterpreterIORedirect(
    Debugger &debugger, CommandReturnObject *result)
    : m_communication("lldb.ScriptInterpreterIORedirect.comm"),
      m_disconnect(false) {

  if (result) {
    m_input_file_sp = debugger.GetInputFileSP();

    Pipe pipe;
    Status pipe_result = pipe.CreateNew();
#if defined(_WIN32)
    lldb::file_t read_file = pipe.GetReadNativeHandle();
    pipe.ReleaseReadFileDescriptor();
    std::unique_ptr<ConnectionGenericFile> conn_up =
        std::make_unique<ConnectionGenericFile>(read_file, true);
#else
    std::unique_ptr<ConnectionFileDescriptor> conn_up =
        std::make_unique<ConnectionFileDescriptor>(
            pipe.ReleaseReadFileDescriptor(), true);
#endif

    if (conn_up->IsConnected()) {
      m_communication.SetConnection(std::move(conn_up));
      m_communication.SetReadThreadBytesReceivedCallback(
          ReadThreadBytesReceived, &result->GetOutputStream());
      m_communication.StartReadThread();
      m_disconnect = true;

      FILE *outfile_handle = fdopen(pipe.ReleaseWriteFileDescriptor(), "w");
      m_output_file_sp = std::make_shared<LockableStreamFile>(
          std::make_shared<StreamFile>(outfile_handle, NativeFile::Owned),
          m_output_mutex);
      m_error_file_sp = m_output_file_sp;
      if (outfile_handle)
        ::setbuf(outfile_handle, nullptr);

      result->SetImmediateOutputFile(debugger.GetOutputFileSP());
      result->SetImmediateErrorFile(debugger.GetErrorFileSP());
    }
  }

  if (!m_input_file_sp || !m_output_file_sp || !m_error_file_sp)
    debugger.AdoptTopIOHandlerFilesIfInvalid(m_input_file_sp, m_output_file_sp,
                                             m_error_file_sp);
}

void ScriptInterpreterIORedirect::Flush() {
  if (m_output_file_sp)
    m_output_file_sp->Lock().Flush();
  if (m_error_file_sp)
    m_error_file_sp->Lock().Flush();
}

ScriptInterpreterIORedirect::~ScriptInterpreterIORedirect() {
  if (!m_disconnect)
    return;

  assert(m_output_file_sp);
  assert(m_error_file_sp);
  assert(m_output_file_sp == m_error_file_sp);

  // Close the write end of the pipe since we are done with our one line
  // script. This should cause the read thread that output_comm is using to
  // exit.
  m_output_file_sp->GetUnlockedFile().Close();
  // The close above should cause this thread to exit when it gets to the end
  // of file, so let it get all its data.
  m_communication.JoinReadThread();
  // Now we can close the read end of the pipe.
  m_communication.Disconnect();
}
