/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "nativebridge/native_bridge.h"
#define LOG_TAG "nativebridge"

#include <dlfcn.h>
#include <errno.h>
#include <string.h>

#include <log/log.h>

namespace android {

namespace {

void* GetLibHandle() {
  static void* handle = dlopen("libnativebridge.so", RTLD_NOW);
  LOG_FATAL_IF(handle == nullptr, "Failed to load libnativebridge.so: %s", dlerror());
  return handle;
}

template <typename FuncPtr>
FuncPtr GetFuncPtr(const char* function_name) {
  auto f = reinterpret_cast<FuncPtr>(dlsym(GetLibHandle(), function_name));
  LOG_FATAL_IF(f == nullptr, "Failed to get address of %s: %s", function_name, dlerror());
  return f;
}

#define GET_FUNC_PTR(name) GetFuncPtr<decltype(&(name))>(#name)

}  // namespace

bool LoadNativeBridge(const char* native_bridge_library_filename,
                      const struct NativeBridgeRuntimeCallbacks* runtime_callbacks) {
  static auto f = GET_FUNC_PTR(LoadNativeBridge);
  return f(native_bridge_library_filename, runtime_callbacks);
}

bool NeedsNativeBridge(const char* instruction_set) {
  static auto f = GET_FUNC_PTR(NeedsNativeBridge);
  return f(instruction_set);
}

bool PreInitializeNativeBridge(const char* app_data_dir, const char* instruction_set) {
  static auto f = GET_FUNC_PTR(PreInitializeNativeBridge);
  return f(app_data_dir, instruction_set);
}

void PreZygoteForkNativeBridge() {
  static auto f = GET_FUNC_PTR(PreZygoteForkNativeBridge);
  return f();
}

bool InitializeNativeBridge(JNIEnv* env, const char* instruction_set) {
  static auto f = GET_FUNC_PTR(InitializeNativeBridge);
  return f(env, instruction_set);
}

void UnloadNativeBridge() {
  static auto f = GET_FUNC_PTR(UnloadNativeBridge);
  return f();
}

bool NativeBridgeAvailable() {
  static auto f = GET_FUNC_PTR(NativeBridgeAvailable);
  return f();
}

bool NativeBridgeInitialized() {
  static auto f = GET_FUNC_PTR(NativeBridgeInitialized);
  return f();
}

void* NativeBridgeLoadLibrary(const char* libpath, int flag) {
  static auto f = GET_FUNC_PTR(NativeBridgeLoadLibrary);
  return f(libpath, flag);
}

void* NativeBridgeGetTrampoline(void* handle, const char* name, const char* shorty, uint32_t len) {
  static auto f = GET_FUNC_PTR(NativeBridgeGetTrampoline);
  return f(handle, name, shorty, len);
}

bool NativeBridgeIsSupported(const char* libpath) {
  static auto f = GET_FUNC_PTR(NativeBridgeIsSupported);
  return f(libpath);
}

uint32_t NativeBridgeGetVersion() {
  static auto f = GET_FUNC_PTR(NativeBridgeGetVersion);
  return f();
}

NativeBridgeSignalHandlerFn NativeBridgeGetSignalHandler(int signal) {
  static auto f = GET_FUNC_PTR(NativeBridgeGetSignalHandler);
  return f(signal);
}

bool NativeBridgeError() {
  static auto f = GET_FUNC_PTR(NativeBridgeError);
  return f();
}

bool NativeBridgeNameAcceptable(const char* native_bridge_library_filename) {
  static auto f = GET_FUNC_PTR(NativeBridgeNameAcceptable);
  return f(native_bridge_library_filename);
}

int NativeBridgeUnloadLibrary(void* handle) {
  static auto f = GET_FUNC_PTR(NativeBridgeUnloadLibrary);
  return f(handle);
}

const char* NativeBridgeGetError() {
  static auto f = GET_FUNC_PTR(NativeBridgeGetError);
  return f();
}

bool NativeBridgeIsPathSupported(const char* path) {
  static auto f = GET_FUNC_PTR(NativeBridgeIsPathSupported);
  return f(path);
}

bool NativeBridgeInitAnonymousNamespace(const char* public_ns_sonames,
                                        const char* anon_ns_library_path) {
  static auto f = GET_FUNC_PTR(NativeBridgeInitAnonymousNamespace);
  return f(public_ns_sonames, anon_ns_library_path);
}

struct native_bridge_namespace_t* NativeBridgeCreateNamespace(
    const char* name, const char* ld_library_path, const char* default_library_path, uint64_t type,
    const char* permitted_when_isolated_path, struct native_bridge_namespace_t* parent_ns) {
  static auto f = GET_FUNC_PTR(NativeBridgeCreateNamespace);
  return f(name, ld_library_path, default_library_path, type, permitted_when_isolated_path,
           parent_ns);
}

bool NativeBridgeLinkNamespaces(struct native_bridge_namespace_t* from,
                                struct native_bridge_namespace_t* to,
                                const char* shared_libs_sonames) {
  static auto f = GET_FUNC_PTR(NativeBridgeLinkNamespaces);
  return f(from, to, shared_libs_sonames);
}

void* NativeBridgeLoadLibraryExt(const char* libpath, int flag,
                                 struct native_bridge_namespace_t* ns) {
  static auto f = GET_FUNC_PTR(NativeBridgeLoadLibraryExt);
  return f(libpath, flag, ns);
}

struct native_bridge_namespace_t* NativeBridgeGetVendorNamespace() {
  static auto f = GET_FUNC_PTR(NativeBridgeGetVendorNamespace);
  return f();
}

#undef GET_FUNC_PTR

}  // namespace android
