#include "lldb/Target/AssertFrameRecognizer.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Symbol/SymbolLocation.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/StackFrameList.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Utility/LLDBLog.h"

using namespace llvm;
using namespace lldb;
using namespace lldb_private;

namespace lldb_private {
/// Fetches the abort frame location depending on the current platform.
///
/// \param[in] triple
///    The target's triple.
/// \param[in,out] location
///    The struct that will contain the abort module spec and symbol names.
/// \return
///    \b true, if the platform is supported
///    \b false, otherwise.
bool GetAbortLocation(const llvm::Triple &triple, SymbolLocation &location) {
  switch (triple.getOS()) {
  case llvm::Triple::Darwin:
  case llvm::Triple::MacOSX:
  case llvm::Triple::IOS:
  case llvm::Triple::TvOS:
  case llvm::Triple::WatchOS:
  case llvm::Triple::BridgeOS:
  case llvm::Triple::DriverKit:
  case llvm::Triple::XROS:
    location.module_spec = FileSpec("libsystem_kernel.dylib");
    location.symbols.push_back(ConstString("__pthread_kill"));
    break;
  case llvm::Triple::Linux:
    location.module_spec = FileSpec("libc.so.6");
    location.symbols.push_back(ConstString("raise"));
    location.symbols.push_back(ConstString("__GI_raise"));
    location.symbols.push_back(ConstString("gsignal"));
    location.symbols.push_back(ConstString("pthread_kill"));
    location.symbols_are_regex = true;
    break;
  case llvm::Triple::Win32:
    if (!triple.isWindowsMSVCEnvironment()) {
      Log *log = GetLog(LLDBLog::Unwind);
      LLDB_LOG(log, "AssertFrameRecognizer::GetAbortLocation Unsupported "
                    "Windows environment");
      return false;
    }
    // Windows MSVC CRT can be statically or dynamically linked. With dynamic
    // linking, abort lives in ucrtbase.dll. With static linking it's embedded
    // in the executable.
    // Match on the symbol only to handle both.
    location.symbols.push_back(ConstString("abort"));
    break;
  default:
    Log *log = GetLog(LLDBLog::Unwind);
    LLDB_LOG(log, "AssertFrameRecognizer::GetAbortLocation Unsupported OS");
    return false;
  }

  return true;
}

/// Fetches the assert frame location depending on the current platform.
///
/// \param[in] triple
///    The target's triple.
/// \param[in,out] location
///    The struct that will contain the assert module spec and symbol names.
/// \return
///    \b true, if the platform is supported
///    \b false, otherwise.
bool GetAssertLocation(const llvm::Triple &triple, SymbolLocation &location) {
  switch (triple.getOS()) {
  case llvm::Triple::Darwin:
  case llvm::Triple::MacOSX:
  case llvm::Triple::IOS:
  case llvm::Triple::TvOS:
  case llvm::Triple::WatchOS:
  case llvm::Triple::BridgeOS:
  case llvm::Triple::DriverKit:
  case llvm::Triple::XROS:
    location.module_spec = FileSpec("libsystem_c.dylib");
    location.symbols.push_back(ConstString("__assert_rtn"));
    break;
  case llvm::Triple::Linux:
    location.module_spec = FileSpec("libc.so.6");
    location.symbols.push_back(ConstString("__assert_fail"));
    location.symbols.push_back(ConstString("__GI___assert_fail"));
    break;
  case llvm::Triple::Win32:
    if (!triple.isWindowsMSVCEnvironment()) {
      Log *log = GetLog(LLDBLog::Unwind);
      LLDB_LOG(log, "AssertFrameRecognizer::GetAssertLocation Unsupported "
                    "Windows environment");
      return false;
    }
    // See comment in GetAbortLocation for why we skip the module check.
    location.symbols.push_back(ConstString("_wassert"));
    break;
  default:
    Log *log = GetLog(LLDBLog::Unwind);
    LLDB_LOG(log, "AssertFrameRecognizer::GetAssertLocation Unsupported OS");
    return false;
  }

  return true;
}

void RegisterAssertFrameRecognizer(Process *process) {
  Target &target = process->GetTarget();
  const llvm::Triple &triple = target.GetArchitecture().GetTriple();
  SymbolLocation location;

  if (!GetAbortLocation(triple, location))
    return;

  if (!location.symbols_are_regex) {
    target.GetFrameRecognizerManager().AddRecognizer(
        std::make_shared<AssertFrameRecognizer>(),
        location.module_spec.GetFilename().str(), location.symbols,
        Mangled::ePreferDemangled,
        /*first_instruction_only*/ false);
    return;
  }
  std::string module_re = "^";
  for (char c : location.module_spec.GetFilename()) {
    if (c == '.')
      module_re += '\\';
    module_re += c;
  }
  module_re += '$';
  std::string symbol_re = "^(";
  for (auto it = location.symbols.cbegin(); it != location.symbols.cend();
       ++it) {
    if (it != location.symbols.cbegin())
      symbol_re += '|';
    symbol_re += it->GetStringRef();
  }
  // Strip the trailing @VER symbol version.
  symbol_re += ")(@.*)?$";
  target.GetFrameRecognizerManager().AddRecognizer(
      std::make_shared<AssertFrameRecognizer>(),
      std::make_shared<RegularExpression>(std::move(module_re)),
      std::make_shared<RegularExpression>(std::move(symbol_re)),
      Mangled::ePreferDemangled,
      /*first_instruction_only*/ false);
}

} // namespace lldb_private

lldb::RecognizedStackFrameSP
AssertFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
  ThreadSP thread_sp = frame_sp->GetThread();
  ProcessSP process_sp = thread_sp->GetProcess();
  Target &target = process_sp->GetTarget();
  const llvm::Triple &triple = target.GetArchitecture().GetTriple();
  SymbolLocation location;

  if (!GetAssertLocation(triple, location))
    return RecognizedStackFrameSP();

  const uint32_t frames_to_fetch = 6;
  const uint32_t last_frame_index = frames_to_fetch - 1;
  StackFrameSP prev_frame_sp = nullptr;

  // Fetch most relevant frame
  for (uint32_t frame_index = 0; frame_index < frames_to_fetch; frame_index++) {
    prev_frame_sp = thread_sp->GetStackFrameAtIndex(frame_index);

    if (!prev_frame_sp) {
      Log *log = GetLog(LLDBLog::Unwind);
      LLDB_LOG(log, "Abort Recognizer: Hit unwinding bound ({} frames)!",
               frames_to_fetch);
      break;
    }

    SymbolContext sym_ctx =
        prev_frame_sp->GetSymbolContext(eSymbolContextEverything);

    if (!sym_ctx.module_sp)
      continue;
    // On Windows the abort/assert symbols may live in the executable (static
    // CRT) or a CRT DLL, so skip the module check there.
    if (!triple.isOSWindows() &&
        !sym_ctx.module_sp->GetFileSpec().FileEquals(location.module_spec))
      continue;

    ConstString func_name = sym_ctx.GetFunctionName();

    if (llvm::is_contained(location.symbols, func_name)) {
      // We go a frame beyond the assert location because the most relevant
      // frame for the user is the one in which the assert function was called.
      // If the assert location is the last frame fetched, then it is set as
      // the most relevant frame.

      StackFrameSP most_relevant_frame_sp = thread_sp->GetStackFrameAtIndex(
          std::min(frame_index + 1, last_frame_index));

      // Pass assert location to AbortRecognizedStackFrame to set as most
      // relevant frame.
      return lldb::RecognizedStackFrameSP(
          new AssertRecognizedStackFrame(most_relevant_frame_sp));
    }
  }

  return RecognizedStackFrameSP();
}

AssertRecognizedStackFrame::AssertRecognizedStackFrame(
    StackFrameSP most_relevant_frame_sp)
    : m_most_relevant_frame(most_relevant_frame_sp) {
  m_stop_desc = "hit program assert";
}

lldb::StackFrameSP AssertRecognizedStackFrame::GetMostRelevantFrame() {
  return m_most_relevant_frame;
}
