/*
 * Copyright (C) 2014 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.
 */

// A simple implementation of the native-bridge interface.

#include <dlfcn.h>
#include <setjmp.h>
#include <signal.h>
#include <sys/stat.h>
#include <unistd.h>

#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <vector>

#include <jni.h>
#include <nativebridge/native_bridge.h>

#include "base/macros.h"

struct NativeBridgeMethod {
  const char* name;
  const char* signature;
  bool static_method;
  void* fnPtr;
  void* trampoline;
};

static NativeBridgeMethod* find_native_bridge_method(const char *name);
static const android::NativeBridgeRuntimeCallbacks* gNativeBridgeArtCallbacks;

static jint trampoline_JNI_OnLoad(JavaVM* vm, void* reserved) {
  JNIEnv* env = nullptr;
  using FnPtr_t = jint(*)(JavaVM*, void*);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>(find_native_bridge_method("JNI_OnLoad")->fnPtr);

  vm->GetEnv(reinterpret_cast<void **>(&env), JNI_VERSION_1_6);
  if (env == nullptr) {
    return 0;
  }

  jclass klass = env->FindClass("Main");
  if (klass != nullptr) {
    int i, count1, count2;
    count1 = gNativeBridgeArtCallbacks->getNativeMethodCount(env, klass);
    std::unique_ptr<JNINativeMethod[]> methods(new JNINativeMethod[count1]);
    if (methods == nullptr) {
      return 0;
    }
    count2 = gNativeBridgeArtCallbacks->getNativeMethods(env, klass, methods.get(), count1);
    if (count1 == count2) {
      printf("Test ART callbacks: all JNI function number is %d.\n", count1);
    }

    for (i = 0; i < count1; i++) {
      NativeBridgeMethod* nb_method = find_native_bridge_method(methods[i].name);
      if (nb_method != nullptr) {
        jmethodID mid = nullptr;
        if (nb_method->static_method) {
          mid = env->GetStaticMethodID(klass, methods[i].name, nb_method->signature);
        } else {
          mid = env->GetMethodID(klass, methods[i].name, nb_method->signature);
        }
        if (mid != nullptr) {
          const char* shorty = gNativeBridgeArtCallbacks->getMethodShorty(env, mid);
          if (strcmp(shorty, methods[i].signature) == 0) {
            printf("    name:%s, signature:%s, shorty:%s.\n",
                   methods[i].name, nb_method->signature, shorty);
          }
        }
      }
    }
    methods.release();
  }

  printf("%s called!\n", __FUNCTION__);
  return fnPtr(vm, reserved);
}

static void trampoline_Java_Main_testFindClassOnAttachedNativeThread(JNIEnv* env, jclass klass) {
  using FnPtr_t = void(*)(JNIEnv*, jclass);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>
    (find_native_bridge_method("testFindClassOnAttachedNativeThread")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass);
}

static void trampoline_Java_Main_testFindFieldOnAttachedNativeThreadNative(JNIEnv* env,
                                                                           jclass klass) {
  using FnPtr_t = void(*)(JNIEnv*, jclass);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>
    (find_native_bridge_method("testFindFieldOnAttachedNativeThreadNative")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass);
}

static void trampoline_Java_Main_testCallStaticVoidMethodOnSubClassNative(JNIEnv* env,
                                                                          jclass klass) {
  using FnPtr_t = void(*)(JNIEnv*, jclass);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>
    (find_native_bridge_method("testCallStaticVoidMethodOnSubClassNative")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass);
}

static jobject trampoline_Java_Main_testGetMirandaMethodNative(JNIEnv* env, jclass klass) {
  using FnPtr_t = jobject(*)(JNIEnv*, jclass);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>
    (find_native_bridge_method("testGetMirandaMethodNative")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass);
}

static void trampoline_Java_Main_testNewStringObject(JNIEnv* env, jclass klass) {
  using FnPtr_t = void(*)(JNIEnv*, jclass);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>
    (find_native_bridge_method("testNewStringObject")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass);
}

static void trampoline_Java_Main_testZeroLengthByteBuffers(JNIEnv* env, jclass klass) {
  using FnPtr_t = void(*)(JNIEnv*, jclass);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>
    (find_native_bridge_method("testZeroLengthByteBuffers")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass);
}

static jbyte trampoline_Java_Main_byteMethod(JNIEnv* env, jclass klass, jbyte b1, jbyte b2,
                                             jbyte b3, jbyte b4, jbyte b5, jbyte b6,
                                             jbyte b7, jbyte b8, jbyte b9, jbyte b10) {
  using FnPtr_t = jbyte(*)(JNIEnv*, jclass, jbyte, jbyte, jbyte, jbyte, jbyte, jbyte, jbyte, jbyte,
                           jbyte, jbyte);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>(find_native_bridge_method("byteMethod")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10);
}

static jshort trampoline_Java_Main_shortMethod(JNIEnv* env, jclass klass, jshort s1, jshort s2,
                                               jshort s3, jshort s4, jshort s5, jshort s6,
                                               jshort s7, jshort s8, jshort s9, jshort s10) {
  using FnPtr_t = jshort(*)(JNIEnv*, jclass, jshort, jshort, jshort, jshort, jshort, jshort, jshort,
                            jshort, jshort, jshort);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>(find_native_bridge_method("shortMethod")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10);
}

static jboolean trampoline_Java_Main_booleanMethod(JNIEnv* env, jclass klass, jboolean b1,
                                                   jboolean b2, jboolean b3, jboolean b4,
                                                   jboolean b5, jboolean b6, jboolean b7,
                                                   jboolean b8, jboolean b9, jboolean b10) {
  using FnPtr_t = jboolean(*)(JNIEnv*, jclass, jboolean, jboolean, jboolean, jboolean, jboolean,
                              jboolean, jboolean, jboolean, jboolean, jboolean);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>(find_native_bridge_method("booleanMethod")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10);
}

static jchar trampoline_Java_Main_charMethod(JNIEnv* env, jclass klass, jchar c1, jchar c2,
                                             jchar c3, jchar c4, jchar c5, jchar c6,
                                             jchar c7, jchar c8, jchar c9, jchar c10) {
  using FnPtr_t = jchar(*)(JNIEnv*, jclass, jchar, jchar, jchar, jchar, jchar, jchar, jchar, jchar,
                           jchar, jchar);
  FnPtr_t fnPtr = reinterpret_cast<FnPtr_t>(find_native_bridge_method("charMethod")->fnPtr);
  printf("%s called!\n", __FUNCTION__);
  return fnPtr(env, klass, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10);
}

// This code is adapted from 004-SignalTest and causes a segfault.
char *go_away_compiler = nullptr;

[[ noreturn ]] static void test_sigaction_handler([[maybe_unused]] int sig,
                                                  [[maybe_unused]] siginfo_t* info,
                                                  [[maybe_unused]] void* context) {
  printf("Should not reach the test sigaction handler.");
  abort();
}

static void raise_sigsegv() {
#if defined(__arm__) || defined(__i386__) || defined(__aarch64__)
  *go_away_compiler = 'a';
#elif defined(__riscv)
  // Cause a SEGV using an instruction known to be 4 bytes long to account for hardcoded jump
  // in the signal handler
  asm volatile("ld zero, (zero);" : : :);
#elif defined(__x86_64__)
  // Cause a SEGV using an instruction known to be 2 bytes long to account for hardcoded jump
  // in the signal handler
  asm volatile("movl $0, %%eax;" "movb %%ah, (%%rax);" : : : "%eax");
#else
  // On other architectures we simulate SEGV.
  kill(getpid(), SIGSEGV);
#endif
}

static jint trampoline_Java_Main_testSignal(JNIEnv*, jclass) {
  // Install the sigaction handler above, which should *not* be reached as the native-bridge
  // handler should be called first. Note: we won't chain at all, if we ever get here, we'll die.
  struct sigaction tmp;
  sigemptyset(&tmp.sa_mask);
  tmp.sa_sigaction = test_sigaction_handler;
#if !defined(__APPLE__)
  tmp.sa_restorer = nullptr;
#endif

  // Test segv
  sigaction(SIGSEGV, &tmp, nullptr);
  raise_sigsegv();

  // Test sigill
  sigaction(SIGILL, &tmp, nullptr);
  kill(getpid(), SIGILL);

#if defined(__BIONIC__)
  // Do the same again, but with sigaction64.
  struct sigaction64 tmp2;
  sigemptyset64(&tmp2.sa_mask);
  tmp2.sa_sigaction = test_sigaction_handler;
#if defined(SA_RESTORER)
  tmp2.sa_restorer = nullptr;
#endif

  sigaction64(SIGSEGV, &tmp2, nullptr);
  sigaction64(SIGILL, &tmp2, nullptr);
#endif

  // Reraise SIGSEGV/SIGILL even on non-bionic, so that the expected output is
  // the same.
  raise_sigsegv();
  kill(getpid(), SIGILL);

  return 1234;
}

// Status of the tricky control path of testSignalHandlerNotReturn.
//
// "kNone" is the default status except testSignalHandlerNotReturn,
// others are used by testSignalHandlerNotReturn.
enum class TestStatus {
  kNone,
  kRaiseFirst,
  kHandleFirst,
  kRaiseSecond,
  kHandleSecond,
};

// State transition helper for testSignalHandlerNotReturn.
class SignalHandlerTestStatus {
 public:
  SignalHandlerTestStatus() : state_(TestStatus::kNone) {
  }

  TestStatus Get() {
    return state_;
  }

  void Reset() {
    Set(TestStatus::kNone);
  }

  void Set(TestStatus state) {
    switch (state) {
      case TestStatus::kNone:
        AssertState(TestStatus::kHandleSecond);
        break;

      case TestStatus::kRaiseFirst:
        AssertState(TestStatus::kNone);
        break;

      case TestStatus::kHandleFirst:
        AssertState(TestStatus::kRaiseFirst);
        break;

      case TestStatus::kRaiseSecond:
        AssertState(TestStatus::kHandleFirst);
        break;

      case TestStatus::kHandleSecond:
        AssertState(TestStatus::kRaiseSecond);
        break;

      default:
        printf("ERROR: unknown state\n");
        abort();
    }

    state_ = state;
  }

 private:
  TestStatus state_;

  void AssertState(TestStatus expected) {
    if (state_ != expected) {
      printf("ERROR: unexpected state, was %d, expected %d\n", state_, expected);
    }
  }
};

static SignalHandlerTestStatus gSignalTestStatus;
// The context is used to jump out from signal handler.
static sigjmp_buf gSignalTestJmpBuf;

// Test whether NativeBridge can receive future signal when its handler doesn't return.
//
// Control path:
//  1. Raise first SIGSEGV in test function.
//  2. Raise another SIGSEGV in NativeBridge's signal handler which is handling
//     the first SIGSEGV.
//  3. Expect that NativeBridge's signal handler invokes again. And jump back
//     to test function in when handling second SIGSEGV.
//  4. Exit test.
//
// NOTE: sigchain should be aware that "special signal handler" may not return.
//       Pay attention if this case fails.
static void trampoline_Java_Main_testSignalHandlerNotReturn(JNIEnv*, jclass) {
  if (gSignalTestStatus.Get() != TestStatus::kNone) {
    printf("ERROR: test already started?\n");
    return;
  }
  printf("start testSignalHandlerNotReturn\n");

  if (sigsetjmp(gSignalTestJmpBuf, 1) == 0) {
    gSignalTestStatus.Set(TestStatus::kRaiseFirst);
    printf("raising first SIGSEGV\n");
    raise_sigsegv();
  } else {
    // jump to here from signal handler when handling second SIGSEGV.
    if (gSignalTestStatus.Get() != TestStatus::kHandleSecond) {
      printf("ERROR: not jump from second SIGSEGV?\n");
      return;
    }
    gSignalTestStatus.Reset();
    printf("back to test from signal handler via siglongjmp(), and done!\n");
  }
}

// Signal handler for testSignalHandlerNotReturn.
// This handler won't return.
static bool NotReturnSignalHandler() {
  if (gSignalTestStatus.Get() == TestStatus::kRaiseFirst) {
    // handling first SIGSEGV
    gSignalTestStatus.Set(TestStatus::kHandleFirst);
    printf("handling first SIGSEGV, will raise another\n");
    sigset_t set;
    sigemptyset(&set);
    sigaddset(&set, SIGSEGV);
    printf("unblock SIGSEGV in handler\n");
    sigprocmask(SIG_UNBLOCK, &set, nullptr);
    gSignalTestStatus.Set(TestStatus::kRaiseSecond);
    printf("raising second SIGSEGV\n");
    raise_sigsegv();    // raise second SIGSEGV
  } else if (gSignalTestStatus.Get() == TestStatus::kRaiseSecond) {
    // handling second SIGSEGV
    gSignalTestStatus.Set(TestStatus::kHandleSecond);
    printf("handling second SIGSEGV, will jump back to test function\n");
    siglongjmp(gSignalTestJmpBuf, 1);
  }
  printf("ERROR: should not reach here!\n");
  return false;
}

NativeBridgeMethod gNativeBridgeMethods[] = {
  { "JNI_OnLoad", "", true, nullptr,
    reinterpret_cast<void*>(trampoline_JNI_OnLoad) },
  { "booleanMethod", "(ZZZZZZZZZZ)Z", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_booleanMethod) },
  { "byteMethod", "(BBBBBBBBBB)B", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_byteMethod) },
  { "charMethod", "(CCCCCCCCCC)C", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_charMethod) },
  { "shortMethod", "(SSSSSSSSSS)S", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_shortMethod) },
  { "testCallStaticVoidMethodOnSubClassNative", "()V", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testCallStaticVoidMethodOnSubClassNative) },
  { "testFindClassOnAttachedNativeThread", "()V", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testFindClassOnAttachedNativeThread) },
  { "testFindFieldOnAttachedNativeThreadNative", "()V", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testFindFieldOnAttachedNativeThreadNative) },
  { "testGetMirandaMethodNative", "()Ljava/lang/reflect/Method;", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testGetMirandaMethodNative) },
  { "testNewStringObject", "()V", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testNewStringObject) },
  { "testZeroLengthByteBuffers", "()V", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testZeroLengthByteBuffers) },
  { "testSignal", "()I", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testSignal) },
  { "testSignalHandlerNotReturn", "()V", true, nullptr,
    reinterpret_cast<void*>(trampoline_Java_Main_testSignalHandlerNotReturn) },
};

static NativeBridgeMethod* find_native_bridge_method(const char *name) {
  const char* pname = name;
  if (strncmp(name, "Java_Main_", 10) == 0) {
    pname += 10;
  }

  for (size_t i = 0; i < sizeof(gNativeBridgeMethods) / sizeof(gNativeBridgeMethods[0]); i++) {
    if (strcmp(pname, gNativeBridgeMethods[i].name) == 0) {
      return &gNativeBridgeMethods[i];
    }
  }
  return nullptr;
}

// NativeBridgeCallbacks implementations
extern "C" bool native_bridge_initialize(const android::NativeBridgeRuntimeCallbacks* art_cbs,
                                         const char* app_code_cache_dir,
                                         [[maybe_unused]] const char* isa) {
  struct stat st;
  if (app_code_cache_dir != nullptr) {
    if (stat(app_code_cache_dir, &st) == 0) {
      if (!S_ISDIR(st.st_mode)) {
        printf("Code cache is not a directory.\n");
      }
    } else {
      perror("Error when stat-ing the code_cache:");
    }
  }

  if (art_cbs != nullptr) {
    gNativeBridgeArtCallbacks = art_cbs;
    printf("Native bridge initialized.\n");
  }
  return true;
}

extern "C" void* native_bridge_loadLibrary(const char* libpath, int flag) {
  if (strstr(libpath, "libinvalid.so") != nullptr) {
    printf("Was to load 'libinvalid.so', force fail.\n");
    return nullptr;
  }
  size_t len = strlen(libpath);
  char* tmp = new char[len + 10];
  strncpy(tmp, libpath, len);
  tmp[len - 3] = '2';
  tmp[len - 2] = '.';
  tmp[len - 1] = 's';
  tmp[len] = 'o';
  tmp[len + 1] = 0;
  void* handle = dlopen(tmp, flag);
  delete[] tmp;

  if (handle == nullptr) {
    printf("Handle = nullptr!\n");
    printf("Was looking for %s.\n", libpath);
    printf("Error = %s.\n", dlerror());
    char cwd[1024] = {'\0'};
    if (getcwd(cwd, sizeof(cwd)) != nullptr) {
      printf("Current working dir: %s\n", cwd);
    }
  }
  return handle;
}

extern "C" void* native_bridge_getTrampoline(void* handle, const char* name, const char* shorty,
                                             [[maybe_unused]] uint32_t len) {
  printf("Getting trampoline for %s with shorty %s.\n", name, shorty);

  // The name here is actually the JNI name, so we can directly do the lookup.
  void* sym = dlsym(handle, name);
  NativeBridgeMethod* method = find_native_bridge_method(name);
  if (method == nullptr)
    return nullptr;
  method->fnPtr = sym;

  return method->trampoline;
}

extern "C" bool native_bridge_isSupported(const char* libpath) {
  printf("Checking for support.\n");

  if (libpath == nullptr) {
    return false;
  }
  // We don't want to hijack javacore. So we should get libarttest...
  return strcmp(libpath, "libjavacore.so") != 0;
}

namespace android {

// Environment values required by the apps running with native bridge.
struct NativeBridgeRuntimeValues {
  const char* os_arch;
  const char* cpu_abi;
  const char* cpu_abi2;
  const char* *supported_abis;
  int32_t abi_count;
};

}  // namespace android

const char* supported_abis[] = {
    "supported1", "supported2", "supported3"
};

const struct android::NativeBridgeRuntimeValues nb_env {
    .os_arch = "os.arch",
    .cpu_abi = "cpu_abi",
    .cpu_abi2 = "cpu_abi2",
    .supported_abis = supported_abis,
    .abi_count = 3
};

extern "C" const struct android::NativeBridgeRuntimeValues* native_bridge_getAppEnv(
    const char* abi) {
  printf("Checking for getEnvValues.\n");

  if (abi == nullptr) {
    return nullptr;
  }

  return &nb_env;
}

// v2 parts.

extern "C" bool native_bridge_isCompatibleWith(uint32_t bridge_version) {
  return bridge_version <= 3;
}

#if defined(__i386__) || defined(__x86_64__)
#if defined(__APPLE__)
#define ucontext __darwin_ucontext

#if defined(__x86_64__)
// 64 bit mac build.
#define CTX_EIP uc_mcontext->__ss.__rip
#else
// 32 bit mac build.
#define CTX_EIP uc_mcontext->__ss.__eip
#endif

#elif defined(__x86_64__)
// 64 bit linux build.
#define CTX_EIP uc_mcontext.gregs[REG_RIP]
#else
// 32 bit linux build.
#define CTX_EIP uc_mcontext.gregs[REG_EIP]
#endif
#endif

static bool StandardSignalHandler(int sig, [[maybe_unused]] siginfo_t* info, void* context) {
  if (sig == SIGSEGV) {
#if defined(__arm__)
    ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
    mcontext_t* mc = reinterpret_cast<mcontext_t*>(&uc->uc_mcontext);
    mc->arm_pc += 2;  // Skip instruction causing segv & sigill.
#elif defined(__aarch64__)
    ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
    mcontext_t* mc = reinterpret_cast<mcontext_t*>(&uc->uc_mcontext);
    mc->pc += 4;  // Skip instruction causing segv & sigill.
#elif defined(__riscv)
    ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
    mcontext_t* mc = reinterpret_cast<mcontext_t*>(&uc->uc_mcontext);
    mc->__gregs[REG_PC] += 4;  // Skip instruction causing segv & sigill.
#elif defined(__i386__)
    ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
    uc->CTX_EIP += 3;
#elif defined(__x86_64__)
    ucontext_t* uc = reinterpret_cast<ucontext_t*>(context);
    uc->CTX_EIP += 2;
#else
    UNUSED(context);
    UNIMPLEMENTED(FATAL) << "Unsupported architecture";
#endif
  }

  // We handled this...
  return true;
}

// A placeholder special handler, continueing after the faulting location. This code comes from
// 004-SignalTest.
static bool nb_signalhandler(int sig, siginfo_t* info, void* context) {
  printf("NB signal handler with signal %d.\n", sig);

  if (gSignalTestStatus.Get() == TestStatus::kNone) {
    return StandardSignalHandler(sig, info, context);
  } else if (sig == SIGSEGV) {
    return NotReturnSignalHandler();
  } else {
    printf("ERROR: should not reach here!\n");
    return false;
  }
}

static ::android::NativeBridgeSignalHandlerFn native_bridge_getSignalHandler(int signal) {
  // Test segv for already claimed signal, and sigill for not claimed signal
  if ((signal == SIGSEGV) || (signal == SIGILL)) {
    return &nb_signalhandler;
  }
  return nullptr;
}

extern "C" int native_bridge_unloadLibrary([[maybe_unused]] void* handle) {
  printf("dlclose() in native bridge.\n");
  return 0;
}

extern "C" const char* native_bridge_getError() {
  printf("getError() in native bridge.\n");
  return "";
}

extern "C" bool native_bridge_isPathSupported([[maybe_unused]] const char* library_path) {
  printf("Checking for path support in native bridge.\n");
  return false;
}

extern "C" bool native_bridge_initAnonymousNamespace(
    [[maybe_unused]] const char* public_ns_sonames,
    [[maybe_unused]] const char* anon_ns_library_path) {
  printf("Initializing anonymous namespace in native bridge.\n");
  return false;
}

extern "C" android::native_bridge_namespace_t*
native_bridge_createNamespace([[maybe_unused]] const char* name,
                              [[maybe_unused]] const char* ld_library_path,
                              [[maybe_unused]] const char* default_library_path,
                              [[maybe_unused]] uint64_t type,
                              [[maybe_unused]] const char* permitted_when_isolated_path,
                              [[maybe_unused]] android::native_bridge_namespace_t* parent_ns) {
  printf("Creating namespace in native bridge.\n");
  return nullptr;
}

extern "C" bool native_bridge_linkNamespaces(
    [[maybe_unused]] android::native_bridge_namespace_t* from,
    [[maybe_unused]] android::native_bridge_namespace_t* to,
    [[maybe_unused]] const char* shared_libs_sonames) {
  printf("Linking namespaces in native bridge.\n");
  return false;
}

extern "C" void* native_bridge_loadLibraryExt(
    [[maybe_unused]] const char* libpath,
    [[maybe_unused]] int flag,
    [[maybe_unused]] android::native_bridge_namespace_t* ns) {
  printf("Loading library with Extension in native bridge.\n");
  return nullptr;
}

// "NativeBridgeItf" is effectively an API (it is the name of the symbol that will be loaded
// by the native bridge library).
android::NativeBridgeCallbacks NativeBridgeItf {
  // v1
  .version = 3,
  .initialize = &native_bridge_initialize,
  .loadLibrary = &native_bridge_loadLibrary,
  .getTrampoline = &native_bridge_getTrampoline,
  .isSupported = &native_bridge_isSupported,
  .getAppEnv = &native_bridge_getAppEnv,
  // v2
  .isCompatibleWith = &native_bridge_isCompatibleWith,
  .getSignalHandler = &native_bridge_getSignalHandler,
  // v3
  .unloadLibrary = &native_bridge_unloadLibrary,
  .getError = &native_bridge_getError,
  .isPathSupported = &native_bridge_isPathSupported,
  .initAnonymousNamespace = &native_bridge_initAnonymousNamespace,
  .createNamespace = &native_bridge_createNamespace,
  .linkNamespaces = &native_bridge_linkNamespaces,
  .loadLibraryExt = &native_bridge_loadLibraryExt
};
