// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "lib/ffi_dynamic_library.h"

#include "platform/globals.h"
#include "platform/utils.h"
#if defined(DART_HOST_OS_WINDOWS)
#include <Psapi.h>
#include <Windows.h>
#include <combaseapi.h>
#include <stdio.h>
#include <tchar.h>
#endif

#include "vm/bootstrap_natives.h"
#include "vm/dart_api_impl.h"
#include "vm/exceptions.h"
#include "vm/ffi/native_assets.h"
#include "vm/native_entry.h"
#include "vm/symbols.h"
#include "vm/zone_text_buffer.h"

#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_MACOS) ||              \
    defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_FUCHSIA)
#include <dlfcn.h>
#endif

namespace dart {

#if defined(USING_SIMULATOR) || (defined(DART_PRECOMPILER) && !defined(TESTING))

DART_NORETURN static void SimulatorUnsupported() {
#if defined(USING_SIMULATOR)
  Exceptions::ThrowUnsupportedError(
      "Not supported on simulated architectures.");
#else
  Exceptions::ThrowUnsupportedError("Not supported in precompiler.");
#endif
}

DEFINE_NATIVE_ENTRY(Ffi_dl_open, 0, 1) {
  SimulatorUnsupported();
}
DEFINE_NATIVE_ENTRY(Ffi_dl_processLibrary, 0, 0) {
  SimulatorUnsupported();
}
DEFINE_NATIVE_ENTRY(Ffi_dl_executableLibrary, 0, 0) {
  SimulatorUnsupported();
}
DEFINE_NATIVE_ENTRY(Ffi_dl_lookup, 1, 2) {
  SimulatorUnsupported();
}
DEFINE_NATIVE_ENTRY(Ffi_dl_getHandle, 0, 1) {
  SimulatorUnsupported();
}
DEFINE_NATIVE_ENTRY(Ffi_dl_close, 0, 1) {
  SimulatorUnsupported();
}
DEFINE_NATIVE_ENTRY(Ffi_dl_providesSymbol, 0, 2) {
  SimulatorUnsupported();
}

DEFINE_NATIVE_ENTRY(Ffi_GetFfiNativeResolver, 1, 0) {
  SimulatorUnsupported();
}

#else  // defined(USING_SIMULATOR) ||                                          \
       // (defined(DART_PRECOMPILER) && !defined(TESTING))

// If an error occurs populates |error| (if provided) with an error message
// (caller must free this message when it is no longer needed).
static void* LoadDynamicLibrary(const char* library_file,
                                char** error = nullptr) {
  char* utils_error = nullptr;
  void* handle = Utils::LoadDynamicLibrary(library_file, &utils_error);
  if (utils_error != nullptr) {
    if (error != nullptr) {
      *error = OS::SCreate(
          /*use malloc*/ nullptr, "Failed to load dynamic library '%s': %s",
          library_file != nullptr ? library_file : "<process>", utils_error);
    }
    free(utils_error);
  }
  return handle;
}

#if defined(DART_HOST_OS_WINDOWS)
// On windows, nullptr signals trying a lookup in all loaded modules.
const nullptr_t kWindowsDynamicLibraryProcessPtr = nullptr;

void* co_task_mem_allocated = nullptr;

// If an error occurs populates |error| with an error message
// (caller must free this message when it is no longer needed).
void* LookupSymbolInProcess(const char* symbol, char** error) {
  // Force loading ole32.dll.
  if (co_task_mem_allocated == nullptr) {
    co_task_mem_allocated = CoTaskMemAlloc(sizeof(intptr_t));
    CoTaskMemFree(co_task_mem_allocated);
  }

  HANDLE current_process =
      OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE,
                  GetCurrentProcessId());
  if (current_process == nullptr) {
    *error = OS::SCreate(nullptr, "Failed to open current process.");
    return nullptr;
  }

  HMODULE modules[1024];
  DWORD cb_needed;
  if (EnumProcessModules(current_process, modules, sizeof(modules),
                         &cb_needed) != 0) {
    for (intptr_t i = 0; i < (cb_needed / sizeof(HMODULE)); i++) {
      if (auto result =
              reinterpret_cast<void*>(GetProcAddress(modules[i], symbol))) {
        CloseHandle(current_process);
        return result;
      }
    }
  }
  CloseHandle(current_process);

  *error = OS::SCreate(
      nullptr,  // Use `malloc`.
      "None of the loaded modules contained the requested symbol '%s'.",
      symbol);
  return nullptr;
}
#endif

// If an error occurs populates |error| with an error message
// (caller must free this message when it is no longer needed).
static void* ResolveSymbol(void* handle, const char* symbol, char** error) {
#if defined(DART_HOST_OS_WINDOWS)
  if (handle == kWindowsDynamicLibraryProcessPtr) {
    return LookupSymbolInProcess(symbol, error);
  }
#endif
  return Utils::ResolveSymbolInDynamicLibrary(handle, symbol, error);
}

static bool SymbolExists(void* handle, const char* symbol) {
  char* error = nullptr;
#if !defined(DART_HOST_OS_WINDOWS)
  Utils::ResolveSymbolInDynamicLibrary(handle, symbol, &error);
#else
  if (handle == nullptr) {
    LookupSymbolInProcess(symbol, &error);
  } else {
    Utils::ResolveSymbolInDynamicLibrary(handle, symbol, &error);
  }
#endif
  if (error != nullptr) {
    free(error);
    return false;
  }
  return true;
}

DEFINE_NATIVE_ENTRY(Ffi_dl_open, 0, 1) {
  GET_NON_NULL_NATIVE_ARGUMENT(String, lib_path, arguments->NativeArgAt(0));

  char* error = nullptr;
  void* handle = LoadDynamicLibrary(lib_path.ToCString(), &error);
  if (error != nullptr) {
    const String& msg = String::Handle(String::New(error));
    free(error);
    Exceptions::ThrowArgumentError(msg);
  }
  return DynamicLibrary::New(handle, true);
}

DEFINE_NATIVE_ENTRY(Ffi_dl_processLibrary, 0, 0) {
#if defined(DART_HOST_OS_LINUX) || defined(DART_HOST_OS_MACOS) ||              \
    defined(DART_HOST_OS_ANDROID) || defined(DART_HOST_OS_FUCHSIA)
  return DynamicLibrary::New(RTLD_DEFAULT, false);
#else
  return DynamicLibrary::New(kWindowsDynamicLibraryProcessPtr, false);
#endif
}

DEFINE_NATIVE_ENTRY(Ffi_dl_executableLibrary, 0, 0) {
  return DynamicLibrary::New(LoadDynamicLibrary(nullptr), false);
}

DEFINE_NATIVE_ENTRY(Ffi_dl_close, 0, 1) {
  GET_NON_NULL_NATIVE_ARGUMENT(DynamicLibrary, dlib, arguments->NativeArgAt(0));
  if (dlib.IsClosed()) {
    // Already closed, nothing to do
  } else if (!dlib.CanBeClosed()) {
    const String& msg = String::Handle(
        String::New("DynamicLibrary.process() and DynamicLibrary.executable() "
                    "can't be closed."));
    Exceptions::ThrowStateError(msg);
  } else {
    void* handle = dlib.GetHandle();
    char* error = nullptr;
    Utils::UnloadDynamicLibrary(handle, &error);

    if (error == nullptr) {
      dlib.SetClosed(true);
    } else {
      const String& msg = String::Handle(String::New(error));
      free(error);
      Exceptions::ThrowStateError(msg);
    }
  }

  return Object::null();
}

DEFINE_NATIVE_ENTRY(Ffi_dl_lookup, 1, 2) {
  GET_NON_NULL_NATIVE_ARGUMENT(DynamicLibrary, dlib, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(String, argSymbolName,
                               arguments->NativeArgAt(1));

  if (dlib.IsClosed()) {
    const String& msg =
        String::Handle(String::New("Cannot lookup symbols in closed library."));
    Exceptions::ThrowStateError(msg);
  }

  void* handle = dlib.GetHandle();

  char* error = nullptr;
  const uword pointer = reinterpret_cast<uword>(
      ResolveSymbol(handle, argSymbolName.ToCString(), &error));
  if (error != nullptr) {
    const String& msg = String::Handle(String::NewFormatted(
        "Failed to lookup symbol '%s': %s", argSymbolName.ToCString(), error));
    free(error);
    Exceptions::ThrowArgumentError(msg);
  }
  return Pointer::New(pointer);
}

DEFINE_NATIVE_ENTRY(Ffi_dl_getHandle, 0, 1) {
  GET_NON_NULL_NATIVE_ARGUMENT(DynamicLibrary, dlib, arguments->NativeArgAt(0));

  intptr_t handle = reinterpret_cast<intptr_t>(dlib.GetHandle());
  return Integer::NewFromUint64(handle);
}

DEFINE_NATIVE_ENTRY(Ffi_dl_providesSymbol, 0, 2) {
  GET_NON_NULL_NATIVE_ARGUMENT(DynamicLibrary, dlib, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(String, argSymbolName,
                               arguments->NativeArgAt(1));

  void* handle = dlib.GetHandle();
  return Bool::Get(SymbolExists(handle, argSymbolName.ToCString())).ptr();
}

// nullptr if no native resolver is installed.
static Dart_FfiNativeResolver GetFfiNativeResolver(Thread* const thread,
                                                   const String& lib_url_str) {
  const Library& lib =
      Library::Handle(Library::LookupLibrary(thread, lib_url_str));
  if (lib.IsNull()) {
    // It is not an error to not have a native resolver installed.
    return nullptr;
  }
  return lib.ffi_native_resolver();
}

// If an error occurs populates |error| with an error message
// (caller must free this message when it is no longer needed).
static void* FfiResolveWithFfiNativeResolver(Thread* const thread,
                                             Dart_FfiNativeResolver resolver,
                                             const String& symbol,
                                             intptr_t args_n,
                                             char** error) {
  auto* result = resolver(symbol.ToCString(), args_n);
  if (result == nullptr) {
    *error = OS::SCreate(/*use malloc*/ nullptr,
                         "Couldn't resolve function: '%s'", symbol.ToCString());
  }
  return result;
}

// Array::null if asset is not in mapping or no mapping.
static ArrayPtr GetAssetLocation(Thread* const thread, const String& asset) {
  Zone* const zone = thread->zone();
  auto& result = Array::Handle(zone);

  const auto& native_assets_map =
      Array::Handle(zone, GetNativeAssetsMap(thread));
  if (!native_assets_map.IsNull()) {
    NativeAssetsMap map(native_assets_map.ptr());
    const auto& lookup = Object::Handle(zone, map.GetOrNull(asset));
    if (!lookup.IsNull()) {
      result = Array::Cast(lookup).ptr();
    }
    map.Release();
  }
  return result.ptr();
}

// String is zone allocated.
static char* AvailableAssetsToCString(Thread* const thread) {
  Zone* const zone = thread->zone();

  const auto& native_assets_map =
      Array::Handle(zone, GetNativeAssetsMap(thread));
  ZoneTextBuffer buffer(zone, 1024);

  if (native_assets_map.IsNull()) {
    buffer.Printf("No available native assets.");
  } else {
    bool first = true;
    buffer.Printf("Available native assets: ");
    NativeAssetsMap map(native_assets_map.ptr());
    NativeAssetsMap::Iterator it(&map);
    auto& asset_id = String::Handle(zone);
    while (it.MoveNext()) {
      if (!first) {
        buffer.Printf(" ,");
        first = false;
      }
      auto entry = it.Current();
      asset_id ^= map.GetKey(entry);
      buffer.Printf("%s", asset_id.ToCString());
    }
    buffer.Printf(".");
    map.Release();
  }
  return buffer.buffer();
}

// If an error occurs populates |error| with an error message
// (caller must free this message when it is no longer needed).
//
// The |asset_location| is formatted as follows:
// ['<path_type>', '<path (optional)>']
// The |asset_location| is conform to: pkg/vm/lib/native_assets/validator.dart
static void* FfiResolveAsset(Thread* const thread,
                             const String& asset,
                             const String& symbol,
                             char** error) {
  void* handle = nullptr;
  NativeAssetsApi* native_assets_api =
      thread->isolate_group()->native_assets_api();
  if (native_assets_api->dlopen != nullptr) {
    // Let embedder resolve the asset id to asset path.
    NoActiveIsolateScope no_active_isolate_scope;
    handle = native_assets_api->dlopen(asset.ToCString(), error);
  }
  if (*error == nullptr && handle == nullptr) {
    // Fall back on VM reading ffi:native-assets from special library in kernel.
    // Allow for both embedder and VM resolution so flutter/engine and
    // flutter/flutter PRs can land without manual roll.
    Zone* const zone = thread->zone();
    const auto& asset_location =
        Array::Handle(zone, GetAssetLocation(thread, asset));
    if (asset_location.IsNull()) {
      return nullptr;
    }

    const auto& asset_type =
        String::Cast(Object::Handle(zone, asset_location.At(0)));
    String& path = String::Handle(zone);
    const char* path_cstr = nullptr;
    if (asset_type.Equals(Symbols::absolute()) ||
        asset_type.Equals(Symbols::relative()) ||
        asset_type.Equals(Symbols::system())) {
      path = String::RawCast(asset_location.At(1));
      path_cstr = path.ToCString();
    }

    if (asset_type.Equals(Symbols::absolute())) {
      if (native_assets_api->dlopen_absolute == nullptr) {
        *error = OS::SCreate(/*use malloc*/ nullptr,
                             "NativeAssetsApi::dlopen_absolute not set.");
        return nullptr;
      }
      NoActiveIsolateScope no_active_isolate_scope;
      handle = native_assets_api->dlopen_absolute(path_cstr, error);
    } else if (asset_type.Equals(Symbols::relative())) {
      if (native_assets_api->dlopen_relative == nullptr) {
        *error = OS::SCreate(/*use malloc*/ nullptr,
                             "NativeAssetsApi::dlopen_relative not set.");
        return nullptr;
      }
      NoActiveIsolateScope no_active_isolate_scope;
      handle = native_assets_api->dlopen_relative(path_cstr, error);
    } else if (asset_type.Equals(Symbols::system())) {
      if (native_assets_api->dlopen_system == nullptr) {
        *error = OS::SCreate(/*use malloc*/ nullptr,
                             "NativeAssetsApi::dlopen_system not set.");
        return nullptr;
      }
      NoActiveIsolateScope no_active_isolate_scope;
      handle = native_assets_api->dlopen_system(path_cstr, error);
    } else if (asset_type.Equals(Symbols::executable())) {
      if (native_assets_api->dlopen_executable == nullptr) {
        *error = OS::SCreate(/*use malloc*/ nullptr,
                             "NativeAssetsApi::dlopen_executable not set.");
        return nullptr;
      }
      NoActiveIsolateScope no_active_isolate_scope;
      handle = native_assets_api->dlopen_executable(error);
    } else {
      RELEASE_ASSERT(asset_type.Equals(Symbols::process()));
      if (native_assets_api->dlopen_process == nullptr) {
        *error = OS::SCreate(/*use malloc*/ nullptr,
                             "NativeAssetsApi::dlopen_process not set.");
        return nullptr;
      }
      NoActiveIsolateScope no_active_isolate_scope;
      handle = native_assets_api->dlopen_process(error);
    }
  }

  if (*error != nullptr) {
    return nullptr;
  }
  if (native_assets_api->dlsym == nullptr) {
    *error =
        OS::SCreate(/*use malloc*/ nullptr, "NativeAssetsApi::dlsym not set.");
    return nullptr;
  }
  void* const result =
      native_assets_api->dlsym(handle, symbol.ToCString(), error);
  return result;
}

// Frees |error|.
static void ThrowFfiResolveError(const String& symbol,
                                 const String& asset,
                                 char* error) {
  const String& error_message = String::Handle(String::NewFormatted(
      "Couldn't resolve native function '%s' in '%s' : %s.\n",
      symbol.ToCString(), asset.ToCString(), error));
  free(error);
  Exceptions::ThrowArgumentError(error_message);
}

intptr_t FfiResolveInternal(const String& asset,
                            const String& symbol,
                            uintptr_t args_n,
                            char** error) {
  Thread* thread = Thread::Current();
  // Resolver resolution.
  auto resolver = GetFfiNativeResolver(thread, asset);
  if (resolver != nullptr) {
    void* ffi_native_result = FfiResolveWithFfiNativeResolver(
        thread, resolver, symbol, args_n, error);
    return reinterpret_cast<intptr_t>(ffi_native_result);
  }

  // Native assets resolution.
  void* asset_result = FfiResolveAsset(thread, asset, symbol, error);
  if (asset_result != nullptr) {
    return reinterpret_cast<intptr_t>(asset_result);
  }

  // Resolution in current process.
#if !defined(DART_HOST_OS_WINDOWS)
  void* const result = Utils::ResolveSymbolInDynamicLibrary(
      RTLD_DEFAULT, symbol.ToCString(), error);
#else
  void* const result = LookupSymbolInProcess(symbol.ToCString(), error);
#endif

  if (*error != nullptr) {
    // Process lookup failed, but the user might have tried to use native
    // asset lookup. So augment the error message to include native assets info.
    char* process_lookup_error = *error;
    NativeAssetsApi* native_assets_api =
        thread->isolate_group()->native_assets_api();
    const char* const format =
        "No asset with id '%s' found. %s "
        "Attempted to fallback to process lookup. %s";
    if (native_assets_api->available_assets != nullptr) {
      // Embedder is resolving asset ids to asset paths.
      char* available_assets = native_assets_api->available_assets();
      *error = OS::SCreate(/*use malloc*/ nullptr, format, asset.ToCString(),
                           available_assets, process_lookup_error);
      free(available_assets);
    } else {
      // VM is resolving asset ids to asset paths.
      *error =
          OS::SCreate(/*use malloc*/ nullptr, format, asset.ToCString(),
                      AvailableAssetsToCString(thread), process_lookup_error);
    }
    free(process_lookup_error);
  }

  return reinterpret_cast<intptr_t>(result);
}

// FFI native C function pointer resolver.
static intptr_t FfiResolve(Dart_Handle asset_handle,
                           Dart_Handle symbol_handle,
                           uintptr_t args_n) {
  auto* const thread = Thread::Current();
  DARTSCOPE(thread);
  auto* const zone = thread->zone();
  const String& asset = Api::UnwrapStringHandle(zone, asset_handle);
  const String& symbol = Api::UnwrapStringHandle(zone, symbol_handle);
  char* error = nullptr;

  const intptr_t result = FfiResolveInternal(asset, symbol, args_n, &error);
  if (error != nullptr) {
    ThrowFfiResolveError(symbol, asset, error);
  }
  ASSERT(result != 0x0);
  return result;
}

// Bootstrap to get the FFI Native resolver through a `native` call.
DEFINE_NATIVE_ENTRY(Ffi_GetFfiNativeResolver, 1, 0) {
  return Pointer::New(reinterpret_cast<intptr_t>(FfiResolve));
}

#endif  // defined(USING_SIMULATOR) ||                                         \
        // (defined(DART_PRECOMPILER) && !defined(TESTING))

}  // namespace dart
