/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing#kwsys for details.  */
#if defined(_WIN32)
#  define NOMINMAX // hide min,max to not conflict with <limits>
#endif

#include "kwsysPrivate.h"
#include KWSYS_HEADER(DynamicLoader.hxx)

#include KWSYS_HEADER(Configure.hxx)
#include KWSYS_HEADER(Encoding.hxx)

// Work-around CMake dependency scanning limitation.  This must
// duplicate the above list of headers.
#if 0
#  include "Configure.hxx.in"
#  include "DynamicLoader.hxx.in"
#endif

// This file actually contains several different implementations:
// * NOOP for environments without dynamic libs
// * HP machines which uses shl_load
// * Mac OS X 10.2.x and earlier which uses NSLinkModule
// * Windows which uses LoadLibrary
// * BeOS / Haiku
// * FreeMiNT for Atari
// * Default implementation for *NIX systems (including Mac OS X 10.3 and
//   later) which use dlopen
//
// Each part of the ifdef contains a complete implementation for
// the static methods of DynamicLoader.

#define CHECK_OPEN_FLAGS(var, supported, ret)                                 \
  do {                                                                        \
    /* Check for unknown flags. */                                            \
    if ((var & AllOpenFlags) != var) {                                        \
      return ret;                                                             \
    }                                                                         \
                                                                              \
    /* Check for unsupported flags. */                                        \
    if ((var & (supported)) != var) {                                         \
      return ret;                                                             \
    }                                                                         \
  } while (0)

namespace KWSYS_NAMESPACE {

DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
  const std::string& libname)
{
  return DynamicLoader::OpenLibrary(libname, 0);
}
}

#if !KWSYS_SUPPORTS_SHARED_LIBS
// Implementation for environments without dynamic libs
#  include <string.h> // for strerror()

namespace KWSYS_NAMESPACE {

DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
  const std::string& libname, int flags)
{
  return 0;
}

int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
  if (!lib) {
    return 0;
  }

  return 1;
}

DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
  DynamicLoader::LibraryHandle lib, const std::string& sym)
{
  return 0;
}

const char* DynamicLoader::LastError()
{
  return "General error";
}

} // namespace KWSYS_NAMESPACE

#elif defined(__hpux)
// Implementation for HPUX machines
#  include <dl.h>
#  include <errno.h>

namespace KWSYS_NAMESPACE {

DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
  const std::string& libname, int flags)
{
  CHECK_OPEN_FLAGS(flags, 0, 0);

  return shl_load(libname.c_str(), BIND_DEFERRED | DYNAMIC_PATH, 0L);
}

int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
  if (!lib) {
    return 0;
  }
  return !shl_unload(lib);
}

DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
  DynamicLoader::LibraryHandle lib, const std::string& sym)
{
  void* addr;
  int status;

  /* TYPE_PROCEDURE Look for a function or procedure. (This used to be default)
   * TYPE_DATA      Look for a symbol in the data segment (for example,
   * variables).
   * TYPE_UNDEFINED Look for any symbol.
   */
  status = shl_findsym(&lib, sym.c_str(), TYPE_UNDEFINED, &addr);
  void* result = (status < 0) ? (void*)0 : addr;

  // Hack to cast pointer-to-data to pointer-to-function.
  return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
}

const char* DynamicLoader::LastError()
{
  // TODO: Need implementation with errno/strerror
  /* If successful, shl_findsym returns an integer (int) value zero. If
   * shl_findsym cannot find sym, it returns -1 and sets errno to zero.
   * If any other errors occur, shl_findsym returns -1 and sets errno to one
   * of these values (defined in <errno.h>):
   * ENOEXEC
   * A format error was detected in the specified library.
   * ENOSYM
   * A symbol on which sym depends could not be found.
   * EINVAL
   * The specified handle is invalid.
   */

  if (errno == ENOEXEC || errno == ENOSYM || errno == EINVAL) {
    return strerror(errno);
  }
  // else
  return 0;
}

} // namespace KWSYS_NAMESPACE

#elif defined(__APPLE__) && (MAC_OS_X_VERSION_MAX_ALLOWED < 1030)
// Implementation for Mac OS X 10.2.x and earlier
#  include <mach-o/dyld.h>
#  include <string.h> // for strlen

namespace KWSYS_NAMESPACE {

DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
  const std::string& libname, int flags)
{
  CHECK_OPEN_FLAGS(flags, 0, 0);

  NSObjectFileImageReturnCode rc;
  NSObjectFileImage image = 0;

  rc = NSCreateObjectFileImageFromFile(libname.c_str(), &image);
  // rc == NSObjectFileImageInappropriateFile when trying to load a dylib file
  if (rc != NSObjectFileImageSuccess) {
    return 0;
  }
  NSModule handle = NSLinkModule(image, libname.c_str(),
                                 NSLINKMODULE_OPTION_BINDNOW |
                                   NSLINKMODULE_OPTION_RETURN_ON_ERROR);
  NSDestroyObjectFileImage(image);
  return handle;
}

int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
  // NSUNLINKMODULE_OPTION_KEEP_MEMORY_MAPPED
  // With  this  option  the memory for the module is not deallocated
  // allowing pointers into the module to still be valid.
  // You should use this option instead if your code experience some problems
  // reported against Panther 10.3.9 (fixed in Tiger 10.4.2 and up)
  bool success = NSUnLinkModule(lib, NSUNLINKMODULE_OPTION_NONE);
  return success;
}

DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
  DynamicLoader::LibraryHandle lib, const std::string& sym)
{
  void* result = 0;
  // Need to prepend symbols with '_' on Apple-gcc compilers
  std::string rsym = '_' + sym;

  NSSymbol symbol = NSLookupSymbolInModule(lib, rsym.c_str());
  if (symbol) {
    result = NSAddressOfSymbol(symbol);
  }

  // Hack to cast pointer-to-data to pointer-to-function.
  return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
}

const char* DynamicLoader::LastError()
{
  return 0;
}

} // namespace KWSYS_NAMESPACE

#elif defined(_WIN32) && !defined(__CYGWIN__)
// Implementation for Windows win32 code but not cygwin
#  include <windows.h>

#  include <stdio.h>

namespace KWSYS_NAMESPACE {

DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
  const std::string& libname, int flags)
{
  CHECK_OPEN_FLAGS(flags, SearchBesideLibrary, NULL);

  DWORD llFlags = 0;
  if (flags & SearchBesideLibrary) {
    llFlags |= LOAD_WITH_ALTERED_SEARCH_PATH;
  }

  return LoadLibraryExW(Encoding::ToWindowsExtendedPath(libname).c_str(), NULL,
                        llFlags);
}

int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
  return (int)FreeLibrary(lib);
}

DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
  DynamicLoader::LibraryHandle lib, const std::string& sym)
{
  // TODO: The calling convention affects the name of the symbol.  We
  // should have a tool to help get the symbol with the desired
  // calling convention.  Currently we assume cdecl.
  //
  // Borland:
  //   __cdecl    = "_func" (default)
  //   __fastcall = "@_func"
  //   __stdcall  = "func"
  //
  // Watcom:
  //   __cdecl    = "_func"
  //   __fastcall = "@_func@X"
  //   __stdcall  = "_func@X"
  //   __watcall  = "func_" (default)
  //
  // MSVC:
  //   __cdecl    = "func" (default)
  //   __fastcall = "@_func@X"
  //   __stdcall  = "_func@X"
  //
  // Note that the "@X" part of the name above is the total size (in
  // bytes) of the arguments on the stack.
  void* result;
#  if defined(__BORLANDC__) || defined(__WATCOMC__)
  // Need to prepend symbols with '_'
  std::string ssym = '_' + sym;
  const char* rsym = ssym.c_str();
#  else
  const char* rsym = sym.c_str();
#  endif
  result = (void*)GetProcAddress(lib, rsym);
// Hack to cast pointer-to-data to pointer-to-function.
#  ifdef __WATCOMC__
  return *(DynamicLoader::SymbolPointer*)(&result);
#  else
  return *reinterpret_cast<DynamicLoader::SymbolPointer*>(&result);
#  endif
}

#  define DYNLOAD_ERROR_BUFFER_SIZE 1024

const char* DynamicLoader::LastError()
{
  wchar_t lpMsgBuf[DYNLOAD_ERROR_BUFFER_SIZE + 1];

  DWORD error = GetLastError();
  DWORD length = FormatMessageW(
    FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, error,
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    lpMsgBuf, DYNLOAD_ERROR_BUFFER_SIZE, NULL);

  static char str[DYNLOAD_ERROR_BUFFER_SIZE + 1];

  if (length < 1) {
    /* FormatMessage failed.  Use a default message.  */
    _snprintf(str, DYNLOAD_ERROR_BUFFER_SIZE,
              "DynamicLoader encountered error 0x%X.  "
              "FormatMessage failed with error 0x%X",
              error, GetLastError());
    return str;
  }

  if (!WideCharToMultiByte(CP_UTF8, 0, lpMsgBuf, -1, str,
                           DYNLOAD_ERROR_BUFFER_SIZE, NULL, NULL)) {
    /* WideCharToMultiByte failed.  Use a default message.  */
    _snprintf(str, DYNLOAD_ERROR_BUFFER_SIZE,
              "DynamicLoader encountered error 0x%X.  "
              "WideCharToMultiByte failed with error 0x%X",
              error, GetLastError());
  }

  return str;
}

} // namespace KWSYS_NAMESPACE

#elif defined(__BEOS__)
// Implementation for BeOS / Haiku
#  include <string.h> // for strerror()

#  include <be/kernel/image.h>
#  include <be/support/Errors.h>

namespace KWSYS_NAMESPACE {

static image_id last_dynamic_err = B_OK;

DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
  const std::string& libname, int flags)
{
  CHECK_OPEN_FLAGS(flags, 0, 0);

  // image_id's are integers, errors are negative. Add one just in case we
  //  get a valid image_id of zero (is that even possible?).
  image_id rc = load_add_on(libname.c_str());
  if (rc < 0) {
    last_dynamic_err = rc;
    return 0;
  }

  return rc + 1;
}

int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
  if (!lib) {
    last_dynamic_err = B_BAD_VALUE;
    return 0;
  } else {
    // The function dlclose() returns 0 on success, and non-zero on error.
    status_t rc = unload_add_on(lib - 1);
    if (rc != B_OK) {
      last_dynamic_err = rc;
      return 0;
    }
  }

  return 1;
}

DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
  DynamicLoader::LibraryHandle lib, const std::string& sym)
{
  // Hack to cast pointer-to-data to pointer-to-function.
  union
  {
    void* pvoid;
    DynamicLoader::SymbolPointer psym;
  } result;

  result.psym = NULL;

  if (!lib) {
    last_dynamic_err = B_BAD_VALUE;
  } else {
    // !!! FIXME: BeOS can do function-only lookups...does this ever
    // !!! FIXME:  actually _want_ a data symbol lookup, or was this union
    // !!! FIXME:  a leftover of dlsym()? (s/ANY/TEXT for functions only).
    status_t rc =
      get_image_symbol(lib - 1, sym.c_str(), B_SYMBOL_TYPE_ANY, &result.pvoid);
    if (rc != B_OK) {
      last_dynamic_err = rc;
      result.psym = NULL;
    }
  }
  return result.psym;
}

const char* DynamicLoader::LastError()
{
  const char* retval = strerror(last_dynamic_err);
  last_dynamic_err = B_OK;
  return retval;
}

} // namespace KWSYS_NAMESPACE

#elif defined(__MINT__)
// Implementation for FreeMiNT on Atari
#  define _GNU_SOURCE /* for program_invocation_name */
#  include <dld.h>
#  include <errno.h>
#  include <malloc.h>
#  include <string.h>

namespace KWSYS_NAMESPACE {

DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
  const std::string& libname, int flags)
{
  CHECK_OPEN_FLAGS(flags, 0, NULL);

  char* name = (char*)calloc(1, libname.size() + 1);
  dld_init(program_invocation_name);
  strncpy(name, libname.c_str(), libname.size());
  dld_link(libname.c_str());
  return (void*)name;
}

int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
  dld_unlink_by_file((char*)lib, 0);
  free(lib);
  return 0;
}

DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
  DynamicLoader::LibraryHandle lib, const std::string& sym)
{
  // Hack to cast pointer-to-data to pointer-to-function.
  union
  {
    void* pvoid;
    DynamicLoader::SymbolPointer psym;
  } result;
  result.pvoid = dld_get_symbol(sym.c_str());
  return result.psym;
}

const char* DynamicLoader::LastError()
{
  return dld_strerror(dld_errno);
}

} // namespace KWSYS_NAMESPACE

#else
// Default implementation for *NIX systems (including Mac OS X 10.3 and
// later) which use dlopen
#  include <dlfcn.h>

namespace KWSYS_NAMESPACE {

DynamicLoader::LibraryHandle DynamicLoader::OpenLibrary(
  const std::string& libname, int flags)
{
  CHECK_OPEN_FLAGS(flags, 0, NULL);

  return dlopen(libname.c_str(), RTLD_LAZY);
}

int DynamicLoader::CloseLibrary(DynamicLoader::LibraryHandle lib)
{
  if (lib) {
    // The function dlclose() returns 0 on success, and non-zero on error.
    return !dlclose(lib);
  }
  // else
  return 0;
}

DynamicLoader::SymbolPointer DynamicLoader::GetSymbolAddress(
  DynamicLoader::LibraryHandle lib, const std::string& sym)
{
  // Hack to cast pointer-to-data to pointer-to-function.
  union
  {
    void* pvoid;
    DynamicLoader::SymbolPointer psym;
  } result;
  result.pvoid = dlsym(lib, sym.c_str());
  return result.psym;
}

const char* DynamicLoader::LastError()
{
  return dlerror();
}

} // namespace KWSYS_NAMESPACE
#endif
