#include "debug_utils-inl.h"  // NOLINT(build/include)
#include "env-inl.h"
#include "node_internals.h"

#ifdef __POSIX__
#if defined(__linux__)
#include <features.h>
#endif

#ifdef __ANDROID__
#include <android/log.h>
#endif

#if defined(__linux__) && !defined(__GLIBC__) || \
    defined(__UCLIBC__) || \
    defined(_AIX) || \
    defined(__Fuchsia__)
#define HAVE_EXECINFO_H 0
#else
#define HAVE_EXECINFO_H 1
#endif

#if HAVE_EXECINFO_H
#include <cxxabi.h>
#include <dlfcn.h>
#include <execinfo.h>
#include <unistd.h>
#include <sys/mman.h>
#include <cstdio>
#endif

#endif  // __POSIX__

#if defined(__linux__) || defined(__sun) || \
    defined(__FreeBSD__) || defined(__OpenBSD__) || \
    defined(__DragonFly__)
#include <link.h>
#endif

#ifdef __APPLE__
#include <mach-o/dyld.h>  // _dyld_get_image_name()
#endif                    // __APPLE__

#ifdef _AIX
#include <sys/ldr.h>  // ld_info structure
#endif                // _AIX

#ifdef _WIN32
#include <Lm.h>
#include <Windows.h>
#include <dbghelp.h>
#include <process.h>
#include <psapi.h>
#include <tchar.h>
#endif  // _WIN32

namespace node {
namespace per_process {
EnabledDebugList enabled_debug_list;
}

void EnabledDebugList::Parse(Environment* env) {
  std::string cats;
  credentials::SafeGetenv("NODE_DEBUG_NATIVE", &cats, env);
  Parse(cats, true);
}

void EnabledDebugList::Parse(const std::string& cats, bool enabled) {
  std::string debug_categories = cats;
  while (!debug_categories.empty()) {
    std::string::size_type comma_pos = debug_categories.find(',');
    std::string wanted = ToLower(debug_categories.substr(0, comma_pos));

#define V(name)                                                                \
  {                                                                            \
    static const std::string available_category = ToLower(#name);              \
    if (available_category.find(wanted) != std::string::npos)                  \
      set_enabled(DebugCategory::name, enabled);                               \
  }

    DEBUG_CATEGORY_NAMES(V)
#undef V

    if (comma_pos == std::string::npos) break;
    // Use everything after the `,` as the list for the next iteration.
    debug_categories = debug_categories.substr(comma_pos + 1);
  }
}

#ifdef __POSIX__
#if HAVE_EXECINFO_H
class PosixSymbolDebuggingContext final : public NativeSymbolDebuggingContext {
 public:
  PosixSymbolDebuggingContext() : pagesize_(getpagesize()) { }

  SymbolInfo LookupSymbol(void* address) override {
    Dl_info info;
    const bool have_info = dladdr(address, &info);
    SymbolInfo ret;
    if (!have_info)
      return ret;

    if (info.dli_sname != nullptr) {
      if (char* demangled =
              abi::__cxa_demangle(info.dli_sname, nullptr, nullptr, nullptr)) {
        ret.name = demangled;
        free(demangled);
      } else {
        ret.name = info.dli_sname;
      }
    }

    if (info.dli_fname != nullptr) {
      ret.filename = info.dli_fname;
    }

    return ret;
  }

  bool IsMapped(void* address) override {
    void* page_aligned = reinterpret_cast<void*>(
        reinterpret_cast<uintptr_t>(address) & ~(pagesize_ - 1));
    return msync(page_aligned, pagesize_, MS_ASYNC) == 0;
  }

  int GetStackTrace(void** frames, int count) override {
    return backtrace(frames, count);
  }

 private:
  uintptr_t pagesize_;
};

std::unique_ptr<NativeSymbolDebuggingContext>
NativeSymbolDebuggingContext::New() {
  return std::make_unique<PosixSymbolDebuggingContext>();
}

#else  // HAVE_EXECINFO_H

std::unique_ptr<NativeSymbolDebuggingContext>
NativeSymbolDebuggingContext::New() {
  return std::make_unique<NativeSymbolDebuggingContext>();
}

#endif  // HAVE_EXECINFO_H

#else  // __POSIX__

class Win32SymbolDebuggingContext final : public NativeSymbolDebuggingContext {
 public:
  Win32SymbolDebuggingContext() {
    current_process_ = GetCurrentProcess();
    USE(SymInitialize(current_process_, nullptr, true));
  }

  ~Win32SymbolDebuggingContext() override {
    USE(SymCleanup(current_process_));
  }

  using NameAndDisplacement = std::pair<std::string, DWORD64>;
  NameAndDisplacement WrappedSymFromAddr(DWORD64 dwAddress) const {
    // Refs: https://docs.microsoft.com/en-us/windows/desktop/Debug/retrieving-symbol-information-by-address
    // Patches:
    // Use `fprintf(stderr, ` instead of `printf`
    // `sym.filename = pSymbol->Name` on success
    // `current_process_` instead of `hProcess.
    DWORD64 dwDisplacement = 0;
    // Patch: made into arg - DWORD64  dwAddress = SOME_ADDRESS;

    char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(TCHAR)];
    const auto pSymbol = reinterpret_cast<PSYMBOL_INFO>(buffer);

    pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
    pSymbol->MaxNameLen = MAX_SYM_NAME;

    if (SymFromAddr(current_process_, dwAddress, &dwDisplacement, pSymbol)) {
      // SymFromAddr returned success
      return NameAndDisplacement(pSymbol->Name, dwDisplacement);
    } else {
      // SymFromAddr failed
      const DWORD error = GetLastError();  // "eat" the error anyway
#ifdef DEBUG
      fprintf(stderr, "SymFromAddr returned error : %lu\n", error);
#endif
    }
    // End MSDN code

    return NameAndDisplacement();
  }

  SymbolInfo WrappedGetLine(DWORD64 dwAddress) const {
    SymbolInfo sym{};

    // Refs: https://docs.microsoft.com/en-us/windows/desktop/Debug/retrieving-symbol-information-by-address
    // Patches:
    // Use `fprintf(stderr, ` instead of `printf`.
    // Assign values to `sym` on success.
    // `current_process_` instead of `hProcess.

    // Patch: made into arg - DWORD64  dwAddress;
    DWORD dwDisplacement;
    IMAGEHLP_LINE64 line;

    SymSetOptions(SYMOPT_LOAD_LINES);

    line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
    // Patch: made into arg - dwAddress = 0x1000000;

    if (SymGetLineFromAddr64(current_process_, dwAddress,
                             &dwDisplacement, &line)) {
      // SymGetLineFromAddr64 returned success
      sym.filename = line.FileName;
      sym.line = line.LineNumber;
    } else {
      // SymGetLineFromAddr64 failed
      const DWORD error = GetLastError();  // "eat" the error anyway
#ifdef DEBUG
      fprintf(stderr, "SymGetLineFromAddr64 returned error : %lu\n", error);
#endif
    }
    // End MSDN code

    return sym;
  }

  // Fills the SymbolInfo::name of the io/out argument `sym`
  std::string WrappedUnDecorateSymbolName(const char* name) const {
    // Refs: https://docs.microsoft.com/en-us/windows/desktop/Debug/retrieving-undecorated-symbol-names
    // Patches:
    // Use `fprintf(stderr, ` instead of `printf`.
    // return `szUndName` instead of `printf` on success
    char szUndName[MAX_SYM_NAME];
    if (UnDecorateSymbolName(name, szUndName, sizeof(szUndName),
                             UNDNAME_COMPLETE)) {
      // UnDecorateSymbolName returned success
      return szUndName;
    } else {
      // UnDecorateSymbolName failed
      const DWORD error = GetLastError();  // "eat" the error anyway
#ifdef DEBUG
      fprintf(stderr, "UnDecorateSymbolName returned error %lu\n", error);
#endif
    }
    return nullptr;
  }

  SymbolInfo LookupSymbol(void* address) override {
    const DWORD64 dw_address = reinterpret_cast<DWORD64>(address);
    SymbolInfo ret = WrappedGetLine(dw_address);
    std::tie(ret.name, ret.dis) = WrappedSymFromAddr(dw_address);
    if (!ret.name.empty()) {
      ret.name = WrappedUnDecorateSymbolName(ret.name.c_str());
    }
    return ret;
  }

  bool IsMapped(void* address) override {
    MEMORY_BASIC_INFORMATION info;

    if (VirtualQuery(address, &info, sizeof(info)) != sizeof(info))
      return false;

    return info.State == MEM_COMMIT && info.Protect != 0;
  }

  int GetStackTrace(void** frames, int count) override {
    return CaptureStackBackTrace(0, count, frames, nullptr);
  }

  Win32SymbolDebuggingContext(const Win32SymbolDebuggingContext&) = delete;
  Win32SymbolDebuggingContext(Win32SymbolDebuggingContext&&) = delete;
  Win32SymbolDebuggingContext operator=(const Win32SymbolDebuggingContext&)
    = delete;
  Win32SymbolDebuggingContext operator=(Win32SymbolDebuggingContext&&)
    = delete;

 private:
  HANDLE current_process_;
};

std::unique_ptr<NativeSymbolDebuggingContext>
NativeSymbolDebuggingContext::New() {
  return std::unique_ptr<NativeSymbolDebuggingContext>(
      new Win32SymbolDebuggingContext());
}

#endif  // __POSIX__

std::string NativeSymbolDebuggingContext::SymbolInfo::Display() const {
  std::ostringstream oss;
  oss << name;
  if (dis != 0) {
    oss << "+" << dis;
  }
  if (!filename.empty()) {
    oss << " [" << filename << ']';
  }
  if (line != 0) {
    oss << ":L" << line;
  }
  return oss.str();
}

void DumpBacktrace(FILE* fp) {
  auto sym_ctx = NativeSymbolDebuggingContext::New();
  void* frames[256];
  const int size = sym_ctx->GetStackTrace(frames, arraysize(frames));
  for (int i = 1; i < size; i += 1) {
    void* frame = frames[i];
    NativeSymbolDebuggingContext::SymbolInfo s = sym_ctx->LookupSymbol(frame);
    fprintf(fp, "%2d: %p %s\n", i, frame, s.Display().c_str());
  }
}

void CheckedUvLoopClose(uv_loop_t* loop) {
  if (uv_loop_close(loop) == 0) return;

  PrintLibuvHandleInformation(loop, stderr);

  fflush(stderr);
  // Finally, abort.
  CHECK(0 && "uv_loop_close() while having open handles");
}

void PrintLibuvHandleInformation(uv_loop_t* loop, FILE* stream) {
  struct Info {
    std::unique_ptr<NativeSymbolDebuggingContext> ctx;
    FILE* stream;
    size_t num_handles;
  };

  Info info { NativeSymbolDebuggingContext::New(), stream, 0 };

  fprintf(stream, "uv loop at [%p] has open handles:\n", loop);

  uv_walk(loop, [](uv_handle_t* handle, void* arg) {
    Info* info = static_cast<Info*>(arg);
    NativeSymbolDebuggingContext* sym_ctx = info->ctx.get();
    FILE* stream = info->stream;
    info->num_handles++;

    fprintf(stream, "[%p] %s%s\n", handle, uv_handle_type_name(handle->type),
            uv_is_active(handle) ? " (active)" : "");

    void* close_cb = reinterpret_cast<void*>(handle->close_cb);
    fprintf(stream, "\tClose callback: %p %s\n",
        close_cb, sym_ctx->LookupSymbol(close_cb).Display().c_str());

    fprintf(stream, "\tData: %p %s\n",
        handle->data, sym_ctx->LookupSymbol(handle->data).Display().c_str());

    // We are also interested in the first field of what `handle->data`
    // points to, because for C++ code that is usually the virtual table pointer
    // and gives us information about the exact kind of object we're looking at.
    void* first_field = nullptr;
    // `handle->data` might be any value, including `nullptr`, or something
    // cast from a completely different type; therefore, check that it’s
    // dereferencable first.
    if (sym_ctx->IsMapped(handle->data))
      first_field = *reinterpret_cast<void**>(handle->data);

    if (first_field != nullptr) {
      fprintf(stream, "\t(First field): %p %s\n",
          first_field, sym_ctx->LookupSymbol(first_field).Display().c_str());
    }
  }, &info);

  fprintf(stream, "uv loop at [%p] has %zu open handles in total\n",
          loop, info.num_handles);
}

std::vector<std::string> NativeSymbolDebuggingContext::GetLoadedLibraries() {
  std::vector<std::string> list;
#if defined(__linux__) || defined(__FreeBSD__) || \
    defined(__OpenBSD__) || defined(__DragonFly__)
  dl_iterate_phdr(
      [](struct dl_phdr_info* info, size_t size, void* data) {
        auto list = static_cast<std::vector<std::string>*>(data);
        if (*info->dlpi_name != '\0') {
          list->push_back(info->dlpi_name);
        }
        return 0;
      },
      &list);
#elif __APPLE__
  uint32_t i = 0;
  for (const char* name = _dyld_get_image_name(i); name != nullptr;
       name = _dyld_get_image_name(++i)) {
    list.push_back(name);
  }

#elif _AIX
  // We can't tell in advance how large the buffer needs to be.
  // Retry until we reach too large a size (1Mb).
  const unsigned int kBufferGrowStep = 4096;
  MallocedBuffer<char> buffer(kBufferGrowStep);
  int rc = -1;
  do {
    rc = loadquery(L_GETINFO, buffer.data, buffer.size);
    if (rc == 0) break;
    buffer = MallocedBuffer<char>(buffer.size + kBufferGrowStep);
  } while (buffer.size < 1024 * 1024);

  if (rc == 0) {
    char* buf = buffer.data;
    ld_info* cur_info = nullptr;
    do {
      std::ostringstream str;
      cur_info = reinterpret_cast<ld_info*>(buf);
      char* member_name = cur_info->ldinfo_filename +
          strlen(cur_info->ldinfo_filename) + 1;
      if (*member_name != '\0') {
        str << cur_info->ldinfo_filename << "(" << member_name << ")";
        list.push_back(str.str());
        str.str("");
      } else {
        list.push_back(cur_info->ldinfo_filename);
      }
      buf += cur_info->ldinfo_next;
    } while (cur_info->ldinfo_next != 0);
  }
#elif __sun
  Link_map* p;

  if (dlinfo(RTLD_SELF, RTLD_DI_LINKMAP, &p) != -1) {
    for (Link_map* l = p; l != nullptr; l = l->l_next) {
      list.push_back(l->l_name);
    }
  }

#elif _WIN32
  // Windows implementation - get a handle to the process.
  HANDLE process_handle = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,
                                      FALSE, GetCurrentProcessId());
  if (process_handle == nullptr) {
    // Cannot proceed, return an empty list.
    return list;
  }
  // Get a list of all the modules in this process
  DWORD size_1 = 0;
  DWORD size_2 = 0;
  // First call to get the size of module array needed
  if (EnumProcessModules(process_handle, nullptr, 0, &size_1)) {
    MallocedBuffer<HMODULE> modules(size_1);

    // Second call to populate the module array
    if (EnumProcessModules(process_handle, modules.data, size_1, &size_2)) {
      for (DWORD i = 0;
           i < (size_1 / sizeof(HMODULE)) && i < (size_2 / sizeof(HMODULE));
           i++) {
        WCHAR module_name[MAX_PATH];
        // Obtain and report the full pathname for each module
        if (GetModuleFileNameExW(process_handle,
                                 modules.data[i],
                                 module_name,
                                 arraysize(module_name) / sizeof(WCHAR))) {
          DWORD size = WideCharToMultiByte(
              CP_UTF8, 0, module_name, -1, nullptr, 0, nullptr, nullptr);
          char* str = new char[size];
          WideCharToMultiByte(
              CP_UTF8, 0, module_name, -1, str, size, nullptr, nullptr);
          list.push_back(str);
        }
      }
    }
  }

  // Release the handle to the process.
  CloseHandle(process_handle);
#endif
  return list;
}

void FWrite(FILE* file, const std::string& str) {
  auto simple_fwrite = [&]() {
    // The return value is ignored because there's no good way to handle it.
    fwrite(str.data(), str.size(), 1, file);
  };

  if (file != stderr && file != stdout) {
    simple_fwrite();
    return;
  }
#ifdef _WIN32
  HANDLE handle =
      GetStdHandle(file == stdout ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE);

  // Check if stderr is something other than a tty/console
  if (handle == INVALID_HANDLE_VALUE || handle == nullptr ||
      uv_guess_handle(_fileno(file)) != UV_TTY) {
    simple_fwrite();
    return;
  }

  // Get required wide buffer size
  int n = MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), nullptr, 0);

  std::vector<wchar_t> wbuf(n);
  MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), wbuf.data(), n);

  WriteConsoleW(handle, wbuf.data(), n, nullptr, nullptr);
  return;
#elif defined(__ANDROID__)
  if (file == stderr) {
    __android_log_print(ANDROID_LOG_ERROR, "nodejs", "%s", str.data());
    return;
  }
#endif
  simple_fwrite();
}

}  // namespace node

extern "C" void __DumpBacktrace(FILE* fp) {
  node::DumpBacktrace(fp);
}
