//===-- 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/Utility/UnimplementedError.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;
}

llvm::Expected<FileSpec> ScriptInterpreter::GenerateExtensionTemplate(
    const std::string &name, std::vector<ExtensionTemplateRequest> &extensions,
    bool generate_non_abstract_methods, std::string output_file) {
  return llvm::make_error<UnimplementedError>();
}

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::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";
  case eScriptedExtensionScriptedCommand:
    return "ScriptedCommand";
  case eScriptedExtensionParsedCommand:
    return "ParsedCommand";
  case eScriptedExtensionScriptedStringSummary:
    return "ScriptedStringSummary";
  case eScriptedExtensionScriptedSyntheticChildren:
    return "ScriptedSyntheticChildren";
  }
  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)
      .CaseLower("ScriptedCommand", eScriptedExtensionScriptedCommand)
      .CaseLower("ParsedCommand", eScriptedExtensionParsedCommand)
      .CaseLower("ScriptedStringSummary",
                 eScriptedExtensionScriptedStringSummary)
      .CaseLower("ScriptedSyntheticChildren",
                 eScriptedExtensionScriptedSyntheticChildren)
      .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();
}
