//===-- ScriptedPythonInterface.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/Host/Config.h"
#include "lldb/Utility/Log.h"
#include "lldb/lldb-enumerations.h"

#if LLDB_ENABLE_PYTHON

// LLDB Python header must be included first
#include "../lldb-python.h"

#include "../ScriptInterpreterPythonImpl.h"
#include "ScriptedPythonInterface.h"
#include "lldb/Core/ModuleSpec.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/FileSpecList.h"
#include "lldb/ValueObject/ValueObjectList.h"
#include <optional>

using namespace lldb;
using namespace lldb_private;

ScriptedPythonInterface::ScriptedPythonInterface(
    ScriptInterpreterPythonImpl &interpreter)
    : ScriptedInterface(), m_interpreter(interpreter) {}

template <>
StructuredData::ArraySP
ScriptedPythonInterface::ExtractValueFromPythonObject<StructuredData::ArraySP>(
    python::PythonObject &p, Status &error) {
  python::PythonList result_list(python::PyRefType::Borrowed, p.get());
  return result_list.CreateStructuredArray();
}

template <>
StructuredData::DictionarySP
ScriptedPythonInterface::ExtractValueFromPythonObject<
    StructuredData::DictionarySP>(python::PythonObject &p, Status &error) {
  python::PythonDictionary result_dict(python::PyRefType::Borrowed, p.get());
  return result_dict.CreateStructuredDictionary();
}

template <>
Status ScriptedPythonInterface::ExtractValueFromPythonObject<Status>(
    python::PythonObject &p, Status &error) {
  if (lldb::SBError *sb_error = reinterpret_cast<lldb::SBError *>(
          python::LLDBSWIGPython_CastPyObjectToSBError(p.get())))
    return m_interpreter.GetStatusFromSBError(*sb_error);
  error =
      Status::FromErrorString("Couldn't cast lldb::SBError to lldb::Status.");

  return {};
}

template <>
Event *ScriptedPythonInterface::ExtractValueFromPythonObject<Event *>(
    python::PythonObject &p, Status &error) {
  if (lldb::SBEvent *sb_event = reinterpret_cast<lldb::SBEvent *>(
          python::LLDBSWIGPython_CastPyObjectToSBEvent(p.get())))
    return m_interpreter.GetOpaqueTypeFromSBEvent(*sb_event);
  error = Status::FromErrorString(
      "Couldn't cast lldb::SBEvent to lldb_private::Event.");

  return nullptr;
}

template <>
lldb::StreamSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StreamSP>(
    python::PythonObject &p, Status &error) {
  if (lldb::SBStream *sb_stream = reinterpret_cast<lldb::SBStream *>(
          python::LLDBSWIGPython_CastPyObjectToSBStream(p.get())))
    return m_interpreter.GetOpaqueTypeFromSBStream(*sb_stream);
  error = Status::FromErrorString(
      "Couldn't cast lldb::SBStream to lldb_private::Stream.");

  return nullptr;
}

template <>
lldb::StackFrameSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StackFrameSP>(
    python::PythonObject &p, Status &error) {
  if (lldb::SBFrame *sb_frame = reinterpret_cast<lldb::SBFrame *>(
          python::LLDBSWIGPython_CastPyObjectToSBFrame(p.get())))
    return m_interpreter.GetOpaqueTypeFromSBFrame(*sb_frame);
  error = Status::FromErrorString(
      "Couldn't cast lldb::SBFrame to lldb_private::StackFrame.");

  return nullptr;
}

template <>
lldb::ThreadSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::ThreadSP>(
    python::PythonObject &p, Status &error) {
  if (lldb::SBThread *sb_thread = reinterpret_cast<lldb::SBThread *>(
          python::LLDBSWIGPython_CastPyObjectToSBThread(p.get())))
    return m_interpreter.GetOpaqueTypeFromSBThread(*sb_thread);
  error = Status::FromErrorString(
      "Couldn't cast lldb::SBThread to lldb_private::Thread.");

  return nullptr;
}

template <>
SymbolContext
ScriptedPythonInterface::ExtractValueFromPythonObject<SymbolContext>(
    python::PythonObject &p, Status &error) {
  if (lldb::SBSymbolContext *sb_symbol_context =
          reinterpret_cast<lldb::SBSymbolContext *>(
              python::LLDBSWIGPython_CastPyObjectToSBSymbolContext(p.get())))
    return m_interpreter.GetOpaqueTypeFromSBSymbolContext(*sb_symbol_context);
  error = Status::FromErrorString(
      "Couldn't cast lldb::SBSymbolContext to lldb_private::SymbolContext.");

  return {};
}

template <>
lldb::DataExtractorSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DataExtractorSP>(
    python::PythonObject &p, Status &error) {
  lldb::SBData *sb_data = reinterpret_cast<lldb::SBData *>(
      python::LLDBSWIGPython_CastPyObjectToSBData(p.get()));

  if (!sb_data) {
    error = Status::FromErrorStringWithFormat(
        "Couldn't cast lldb::SBData to lldb::DataExtractorSP.");
    return nullptr;
  }

  return m_interpreter.GetDataExtractorFromSBData(*sb_data);
}

template <>
lldb::BreakpointSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::BreakpointSP>(
    python::PythonObject &p, Status &error) {
  lldb::SBBreakpoint *sb_breakpoint = reinterpret_cast<lldb::SBBreakpoint *>(
      python::LLDBSWIGPython_CastPyObjectToSBBreakpoint(p.get()));

  if (!sb_breakpoint) {
    error = Status::FromErrorStringWithFormat(
        "Couldn't cast lldb::SBBreakpoint to lldb::BreakpointSP.");
    return nullptr;
  }

  return m_interpreter.GetOpaqueTypeFromSBBreakpoint(*sb_breakpoint);
}

template <>
lldb::BreakpointLocationSP
ScriptedPythonInterface::ExtractValueFromPythonObject<
    lldb::BreakpointLocationSP>(python::PythonObject &p, Status &error) {
  lldb::SBBreakpointLocation *sb_break_loc =
      reinterpret_cast<lldb::SBBreakpointLocation *>(
          python::LLDBSWIGPython_CastPyObjectToSBBreakpointLocation(p.get()));

  if (!sb_break_loc) {
    error = Status::FromErrorStringWithFormat(
        "Couldn't cast lldb::SBBreakpointLocation to "
        "lldb::BreakpointLocationSP.");
    return nullptr;
  }

  return m_interpreter.GetOpaqueTypeFromSBBreakpointLocation(*sb_break_loc);
}

template <>
lldb::ProcessAttachInfoSP ScriptedPythonInterface::ExtractValueFromPythonObject<
    lldb::ProcessAttachInfoSP>(python::PythonObject &p, Status &error) {
  lldb::SBAttachInfo *sb_attach_info = reinterpret_cast<lldb::SBAttachInfo *>(
      python::LLDBSWIGPython_CastPyObjectToSBAttachInfo(p.get()));

  if (!sb_attach_info) {
    error = Status::FromErrorStringWithFormat(
        "Couldn't cast lldb::SBAttachInfo to lldb::ProcessAttachInfoSP.");
    return nullptr;
  }

  return m_interpreter.GetOpaqueTypeFromSBAttachInfo(*sb_attach_info);
}

template <>
lldb::ProcessLaunchInfoSP ScriptedPythonInterface::ExtractValueFromPythonObject<
    lldb::ProcessLaunchInfoSP>(python::PythonObject &p, Status &error) {
  lldb::SBLaunchInfo *sb_launch_info = reinterpret_cast<lldb::SBLaunchInfo *>(
      python::LLDBSWIGPython_CastPyObjectToSBLaunchInfo(p.get()));

  if (!sb_launch_info) {
    error = Status::FromErrorStringWithFormat(
        "Couldn't cast lldb::SBLaunchInfo to lldb::ProcessLaunchInfoSP.");
    return nullptr;
  }

  return m_interpreter.GetOpaqueTypeFromSBLaunchInfo(*sb_launch_info);
}

template <>
std::optional<MemoryRegionInfo>
ScriptedPythonInterface::ExtractValueFromPythonObject<
    std::optional<MemoryRegionInfo>>(python::PythonObject &p, Status &error) {

  lldb::SBMemoryRegionInfo *sb_mem_reg_info =
      reinterpret_cast<lldb::SBMemoryRegionInfo *>(
          python::LLDBSWIGPython_CastPyObjectToSBMemoryRegionInfo(p.get()));

  if (!sb_mem_reg_info) {
    error = Status::FromErrorStringWithFormat(
        "Couldn't cast lldb::SBMemoryRegionInfo to "
        "lldb_private::MemoryRegionInfo.");
    return {};
  }

  return m_interpreter.GetOpaqueTypeFromSBMemoryRegionInfo(*sb_mem_reg_info);
}

template <>
lldb::ExecutionContextRefSP
ScriptedPythonInterface::ExtractValueFromPythonObject<
    lldb::ExecutionContextRefSP>(python::PythonObject &p, Status &error) {

  lldb::SBExecutionContext *sb_exe_ctx =
      reinterpret_cast<lldb::SBExecutionContext *>(
          python::LLDBSWIGPython_CastPyObjectToSBExecutionContext(p.get()));

  if (!sb_exe_ctx) {
    error = Status::FromErrorStringWithFormat(
        "Couldn't cast lldb::SBExecutionContext to "
        "lldb::ExecutionContextRefSP.");
    return {};
  }

  return m_interpreter.GetOpaqueTypeFromSBExecutionContext(*sb_exe_ctx);
}

template <>
lldb::DescriptionLevel
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::DescriptionLevel>(
    python::PythonObject &p, Status &error) {
  lldb::DescriptionLevel ret_val = lldb::eDescriptionLevelBrief;
  llvm::Expected<unsigned long long> unsigned_or_err = p.AsUnsignedLongLong();
  if (!unsigned_or_err) {
    error = (Status::FromError(unsigned_or_err.takeError()));
    return ret_val;
  }
  unsigned long long unsigned_val = *unsigned_or_err;
  if (unsigned_val >= lldb::DescriptionLevel::kNumDescriptionLevels) {
    error = Status("value too large for lldb::DescriptionLevel.");
    return ret_val;
  }
  return static_cast<lldb::DescriptionLevel>(unsigned_val);
}

template <>
lldb::StackFrameListSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::StackFrameListSP>(
    python::PythonObject &p, Status &error) {

  lldb::SBFrameList *sb_frame_list = reinterpret_cast<lldb::SBFrameList *>(
      python::LLDBSWIGPython_CastPyObjectToSBFrameList(p.get()));

  if (!sb_frame_list) {
    error = Status::FromErrorStringWithFormat(
        "couldn't cast lldb::SBFrameList to lldb::StackFrameListSP.");
    return {};
  }

  return m_interpreter.GetOpaqueTypeFromSBFrameList(*sb_frame_list);
}

template <>
lldb::ValueObjectSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::ValueObjectSP>(
    python::PythonObject &p, Status &error) {
  lldb::SBValue *sb_value = reinterpret_cast<lldb::SBValue *>(
      python::LLDBSWIGPython_CastPyObjectToSBValue(p.get()));
  if (!sb_value) {
    error = Status::FromErrorStringWithFormat(
        "couldn't cast lldb::SBValue to lldb::ValueObjectSP");
    return {};
  }

  return m_interpreter.GetOpaqueTypeFromSBValue(*sb_value);
}

template <>
lldb::ValueObjectListSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::ValueObjectListSP>(
    python::PythonObject &p, Status &error) {
  lldb::SBValueList *sb_value_list = reinterpret_cast<lldb::SBValueList *>(
      python::LLDBSWIGPython_CastPyObjectToSBValueList(p.get()));

  if (!sb_value_list) {
    error = Status::FromErrorStringWithFormat(
        "couldn't cast lldb::SBValueList to lldb::ValueObjectListSP");
    return {};
  }

  lldb::ValueObjectListSP out = std::make_shared<ValueObjectList>();
  for (uint32_t i = 0, e = sb_value_list->GetSize(); i < e; ++i) {
    SBValue value = sb_value_list->GetValueAtIndex(i);
    out->Append(m_interpreter.GetOpaqueTypeFromSBValue(value));
  }

  return out;
}

template <>
FileSpec ScriptedPythonInterface::ExtractValueFromPythonObject<FileSpec>(
    python::PythonObject &p, Status &error) {
  if (lldb::SBFileSpec *sb_file_spec = reinterpret_cast<lldb::SBFileSpec *>(
          python::LLDBSWIGPython_CastPyObjectToSBFileSpec(p.get()))) {
    if (auto file_spec =
            m_interpreter.GetOpaqueTypeFromSBFileSpec(*sb_file_spec))
      return *file_spec;
  }
  error = Status::FromErrorString(
      "couldn't cast lldb::SBFileSpec to lldb_private::FileSpec.");

  return {};
}

template <>
ModuleSpec ScriptedPythonInterface::ExtractValueFromPythonObject<ModuleSpec>(
    python::PythonObject &p, Status &error) {
  if (lldb::SBModuleSpec *sb_module_spec =
          reinterpret_cast<lldb::SBModuleSpec *>(
              python::LLDBSWIGPython_CastPyObjectToSBModuleSpec(p.get()))) {
    if (auto module_spec =
            m_interpreter.GetOpaqueTypeFromSBModuleSpec(*sb_module_spec))
      return *module_spec;
  }
  error = Status::FromErrorString(
      "couldn't cast lldb::SBModuleSpec to lldb_private::ModuleSpec.");

  return {};
}

template <>
FileSpecList
ScriptedPythonInterface::ExtractValueFromPythonObject<FileSpecList>(
    python::PythonObject &p, Status &error) {
  FileSpecList result;
  if (lldb::SBFileSpecList *sb_list = reinterpret_cast<lldb::SBFileSpecList *>(
          python::LLDBSWIGPython_CastPyObjectToSBFileSpecList(p.get()))) {
    for (uint32_t i = 0; i < sb_list->GetSize(); i++) {
      lldb::SBFileSpec sb_file_spec = sb_list->GetFileSpecAtIndex(i);
      if (auto file_spec =
              m_interpreter.GetOpaqueTypeFromSBFileSpec(sb_file_spec))
        result.Append(*file_spec);
    }
    return result;
  }
  error = Status::FromErrorString(
      "couldn't cast Python object to lldb::SBFileSpecList.");
  return result;
}

template <>
lldb::ModuleSP
ScriptedPythonInterface::ExtractValueFromPythonObject<lldb::ModuleSP>(
    python::PythonObject &p, Status &error) {
  if (lldb::SBModule *sb_module = reinterpret_cast<lldb::SBModule *>(
          python::LLDBSWIGPython_CastPyObjectToSBModule(p.get())))
    return m_interpreter.GetOpaqueTypeFromSBModule(*sb_module);
  error = Status::FromErrorString(
      "couldn't cast lldb::SBModule to lldb::ModuleSP.");

  return {};
}

// MakeSBModuleSpec is defined here rather than in ScriptInterpreter.cpp
// because it constructs an SBModuleSpec, whose symbols live in liblldb.
// ScriptInterpreter.cpp is part of lldbInterpreter which is also linked
// into lldb-server, which does not link the API library.
std::unique_ptr<lldb::SBModuleSpec>
ScriptInterpreter::MakeSBModuleSpec(const ModuleSpec &module_spec) const {
  return std::unique_ptr<lldb::SBModuleSpec>(
      new lldb::SBModuleSpec(module_spec));
}

#endif
