// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/fml/backtrace.h"

#include <cxxabi.h>
#include <dlfcn.h>
#include <execinfo.h>

#include <csignal>
#include <sstream>

#if OS_WIN
#include <crtdbg.h>
#include <debugapi.h>
#endif

#include "flutter/fml/logging.h"
#include "flutter/fml/paths.h"
#include "third_party/abseil-cpp/absl/debugging/symbolize.h"

namespace fml {

static std::string kKUnknownFrameName = "Unknown";

static std::string DemangleSymbolName(const std::string& mangled) {
  if (mangled == kKUnknownFrameName) {
    return kKUnknownFrameName;
  }

  int status = 0;
  size_t length = 0;
  char* demangled = __cxxabiv1::__cxa_demangle(
      mangled.data(),  // mangled name
      nullptr,         // output buffer (malloc-ed if nullptr)
      &length,         // demangled length
      &status);

  if (demangled == nullptr || status != 0) {
    return mangled;
  }

  auto demangled_string = std::string{demangled, length};
  free(demangled);
  return demangled_string;
}

static std::string GetSymbolName(void* symbol) {
  char name[1024];
  if (!absl::Symbolize(symbol, name, sizeof(name))) {
    return kKUnknownFrameName;
  }

  return DemangleSymbolName({name});
}

std::string BacktraceHere(size_t offset) {
  constexpr size_t kMaxFrames = 256;
  void* symbols[kMaxFrames];
  const auto available_frames = ::backtrace(symbols, kMaxFrames);
  if (available_frames <= 0) {
    return "";
  }

  std::stringstream stream;
  for (int i = 1 + offset; i < available_frames; ++i) {
    stream << "Frame " << i - 1 - offset << ": " << symbols[i] << " "
           << GetSymbolName(symbols[i]) << std::endl;
  }
  return stream.str();
}

static size_t kKnownSignalHandlers[] = {
    SIGABRT,  // abort program
    SIGFPE,   // floating-point exception
    SIGBUS,   // bus error
    SIGSEGV,  // segmentation violation
    SIGSYS,   // non-existent system call invoked
    SIGPIPE,  // write on a pipe with no reader
    SIGALRM,  // real-time timer expired
    SIGTERM,  // software termination signal
};

static std::string SignalNameToString(int signal) {
  switch (signal) {
    case SIGABRT:
      return "SIGABRT";
    case SIGFPE:
      return "SIGFPE";
    case SIGBUS:
      return "SIGBUS";
    case SIGSEGV:
      return "SIGSEGV";
    case SIGSYS:
      return "SIGSYS";
    case SIGPIPE:
      return "SIGPIPE";
    case SIGALRM:
      return "SIGALRM";
    case SIGTERM:
      return "SIGTERM";
  };
  return std::to_string(signal);
}

static void ToggleSignalHandlers(bool set);

static void SignalHandler(int signal) {
  // We are a crash signal handler. This can only happen once. Since we don't
  // want to catch crashes while we are generating the crash reports, disable
  // all set signal handlers to their default values before reporting the crash
  // and re-raising the signal.
  ToggleSignalHandlers(false);

  FML_LOG(ERROR) << "Caught signal " << SignalNameToString(signal)
                 << " during program execution." << std::endl
                 << BacktraceHere(3);

  ::raise(signal);
}

static void ToggleSignalHandlers(bool set) {
  for (size_t i = 0; i < sizeof(kKnownSignalHandlers) / sizeof(size_t); ++i) {
    auto signal_name = kKnownSignalHandlers[i];
    auto handler = set ? &SignalHandler : SIG_DFL;

    if (::signal(signal_name, handler) == SIG_ERR) {
      FML_LOG(ERROR) << "Could not attach signal handler for " << signal_name;
    }
  }
}

void InstallCrashHandler() {
#if OS_WIN
  if (!IsDebuggerPresent()) {
    _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG);
    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR);
  }
#endif
  auto exe_path = fml::paths::GetExecutablePath();
  if (exe_path.first) {
    absl::InitializeSymbolizer(exe_path.second.c_str());
  }
  ToggleSignalHandlers(true);
}

bool IsCrashHandlingSupported() {
  return true;
}

}  // namespace fml
