//===----------------------------------------------------------------------===//
//
// 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-python.h"

#include "lldb/Breakpoint/Breakpoint.h"
#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Breakpoint/BreakpointResolverScripted.h"
#include "lldb/Core/PluginManager.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/ExecutionContext.h"
#include "lldb/Utility/Log.h"
#include "lldb/lldb-enumerations.h"

#include "../SWIGPythonBridge.h"
#include "../ScriptInterpreterPythonImpl.h"
#include "ScriptedBreakpointPythonInterface.h"

using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::python;

ScriptedBreakpointPythonInterface::ScriptedBreakpointPythonInterface(
    ScriptInterpreterPythonImpl &interpreter)
    : ScriptedBreakpointInterface(), ScriptedPythonInterface(interpreter) {}

llvm::Expected<StructuredData::GenericSP>
ScriptedBreakpointPythonInterface::CreatePluginObject(
    const ScriptedMetadata &scripted_metadata, lldb::BreakpointSP break_sp) {
  return ScriptedPythonInterface::CreatePluginObject(
      scripted_metadata, nullptr, break_sp, scripted_metadata.GetArgsSP());
}

bool ScriptedBreakpointPythonInterface::OverridesResolver(
    Target &target, StructuredDataImpl &resolver_data) {
  Status error;

  TargetSP target_sp = target.shared_from_this();

  StructuredData::ObjectSP obj =
      Dispatch("overrides_resolver", error, target_sp, resolver_data);

  if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
                                                    error)) {
    Log *log = GetLog(LLDBLog::Script);
    LLDB_LOG(log, "Error calling overrides_resolver method: {0}", error);
    return false;
  }
  return obj->GetBooleanValue();
}

void ScriptedBreakpointPythonInterface::SetBreakpoint(
    lldb::BreakpointSP break_sp) {
  Status error;
  StructuredData::ObjectSP obj = Dispatch("set_breakpoint", error, break_sp);
  if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
                                                    error)) {
    Log *log = GetLog(LLDBLog::Script);
    LLDB_LOG(log, "Error calling set_breakpoint method: {0}", error);
  }
}

bool ScriptedBreakpointPythonInterface::ResolverCallback(
    SymbolContext sym_ctx) {
  Status error;

  StructuredData::ObjectSP obj = Dispatch("__callback__", error, sym_ctx);

  if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
                                                    error)) {
    Log *log = GetLog(LLDBLog::Script);
    LLDB_LOG(log, "Error calling __callback__ method: {}", error);
    return true;
  }
  return obj->GetBooleanValue();
}

lldb::SearchDepth ScriptedBreakpointPythonInterface::GetDepth() {
  Status error;
  StructuredData::ObjectSP obj = Dispatch("__get_depth__", error);

  if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
                                                    error)) {
    return lldb::eSearchDepthModule;
  }
  uint64_t value = obj->GetUnsignedIntegerValue();
  if (value <= lldb::kLastSearchDepthKind)
    return (lldb::SearchDepth)value;
  // This is what we were doing on error before, though I'm not sure that's
  // better than returning eSearchDepthInvalid.
  return lldb::eSearchDepthModule;
}

std::optional<std::string> ScriptedBreakpointPythonInterface::GetShortHelp() {
  Status error;
  StructuredData::ObjectSP obj = Dispatch("get_short_help", error);

  if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
                                                    error)) {
    return {};
  }

  return obj->GetAsString()->GetValue().str();
}

lldb::BreakpointLocationSP ScriptedBreakpointPythonInterface::WasHit(
    lldb::StackFrameSP frame_sp, lldb::BreakpointLocationSP bp_loc_sp) {
  Status py_error;
  lldb::BreakpointLocationSP loc_sp = Dispatch<lldb::BreakpointLocationSP>(
      "was_hit", py_error, frame_sp, bp_loc_sp);

  if (py_error.Fail())
    return bp_loc_sp;

  return loc_sp;
}

std::optional<std::string>
ScriptedBreakpointPythonInterface::GetLocationDescription(
    lldb::BreakpointLocationSP bp_loc_sp, lldb::DescriptionLevel level) {
  Status error;
  StructuredData::ObjectSP obj =
      Dispatch("get_location_description", error, bp_loc_sp, level);

  if (!ScriptedInterface::CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, obj,
                                                    error))
    return {};

  return obj->GetAsString()->GetValue().str();
}

void ScriptedBreakpointPythonInterface::Initialize() {
  const std::vector<llvm::StringRef> ci_usages = {
      "breakpoint set -P classname [-k key -v value ...]"};
  const std::vector<llvm::StringRef> api_usages = {
      "SBTarget.BreakpointCreateFromScript"};
  PluginManager::RegisterPlugin(
      GetPluginNameStatic(),
      llvm::StringRef("Create a breakpoint that chooses locations based on "
                      "user-created callbacks"),
      CreateInstance, eScriptedExtensionScriptedBreakpointResolver,
      eScriptLanguagePython, {ci_usages, api_usages});
}

void ScriptedBreakpointPythonInterface::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
}
