//===-- 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"
#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::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();
}

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<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::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;
}

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>();
}

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 nullin.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();
}
