/*
 * 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 <dlfcn.h>
#include <memory>
#include <unordered_map>

#include <android-base/strings.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <jni.h>

#include "native_loader_namespace.h"
#include "nativehelper/scoped_utf_chars.h"
#include "nativeloader/dlext_namespaces.h"
#include "nativeloader/native_loader.h"
#include "public_libraries.h"

namespace android {
namespace nativeloader {

using ::testing::Eq;
using ::testing::Return;
using ::testing::StrEq;
using ::testing::_;
using internal::ConfigEntry;
using internal::ParseConfig;

#if defined(__LP64__)
#define LIB_DIR "lib64"
#else
#define LIB_DIR "lib"
#endif

// gmock interface that represents interested platform APIs on libdl and libnativebridge
class Platform {
 public:
  virtual ~Platform() {}

  // libdl APIs
  virtual void* dlopen(const char* filename, int flags) = 0;
  virtual int dlclose(void* handle) = 0;
  virtual char* dlerror(void) = 0;

  // These mock_* are the APIs semantically the same across libdl and libnativebridge.
  // Instead of having two set of mock APIs for the two, define only one set with an additional
  // argument 'bool bridged' to identify the context (i.e., called for libdl or libnativebridge).
  typedef char* mock_namespace_handle;
  virtual bool mock_init_anonymous_namespace(bool bridged, const char* sonames,
                                             const char* search_paths) = 0;
  virtual mock_namespace_handle mock_create_namespace(
      bool bridged, const char* name, const char* ld_library_path, const char* default_library_path,
      uint64_t type, const char* permitted_when_isolated_path, mock_namespace_handle parent) = 0;
  virtual bool mock_link_namespaces(bool bridged, mock_namespace_handle from,
                                    mock_namespace_handle to, const char* sonames) = 0;
  virtual mock_namespace_handle mock_get_exported_namespace(bool bridged, const char* name) = 0;
  virtual void* mock_dlopen_ext(bool bridged, const char* filename, int flags,
                                mock_namespace_handle ns) = 0;

  // libnativebridge APIs for which libdl has no corresponding APIs
  virtual bool NativeBridgeInitialized() = 0;
  virtual const char* NativeBridgeGetError() = 0;
  virtual bool NativeBridgeIsPathSupported(const char*) = 0;
  virtual bool NativeBridgeIsSupported(const char*) = 0;

  // To mock "ClassLoader Object.getParent()"
  virtual const char* JniObject_getParent(const char*) = 0;
};

// The mock does not actually create a namespace object. But simply casts the pointer to the
// string for the namespace name as the handle to the namespace object.
#define TO_ANDROID_NAMESPACE(str) \
  reinterpret_cast<struct android_namespace_t*>(const_cast<char*>(str))

#define TO_BRIDGED_NAMESPACE(str) \
  reinterpret_cast<struct native_bridge_namespace_t*>(const_cast<char*>(str))

#define TO_MOCK_NAMESPACE(ns) reinterpret_cast<Platform::mock_namespace_handle>(ns)

// These represents built-in namespaces created by the linker according to ld.config.txt
static std::unordered_map<std::string, Platform::mock_namespace_handle> namespaces = {
    {"system", TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE("system"))},
    {"default", TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE("default"))},
    {"art", TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE("art"))},
    {"sphal", TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE("sphal"))},
    {"vndk", TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE("vndk"))},
    {"neuralnetworks", TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE("neuralnetworks"))},
    {"cronet", TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE("cronet"))},
};

// The actual gmock object
class MockPlatform : public Platform {
 public:
  explicit MockPlatform(bool is_bridged) : is_bridged_(is_bridged) {
    ON_CALL(*this, NativeBridgeIsSupported(_)).WillByDefault(Return(is_bridged_));
    ON_CALL(*this, NativeBridgeIsPathSupported(_)).WillByDefault(Return(is_bridged_));
    ON_CALL(*this, mock_get_exported_namespace(_, _))
        .WillByDefault(testing::Invoke([](bool, const char* name) -> mock_namespace_handle {
          if (namespaces.find(name) != namespaces.end()) {
            return namespaces[name];
          }
          return TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE("(namespace not found"));
        }));
  }

  // Mocking libdl APIs
  MOCK_METHOD2(dlopen, void*(const char*, int));
  MOCK_METHOD1(dlclose, int(void*));
  MOCK_METHOD0(dlerror, char*());

  // Mocking the common APIs
  MOCK_METHOD3(mock_init_anonymous_namespace, bool(bool, const char*, const char*));
  MOCK_METHOD7(mock_create_namespace,
               mock_namespace_handle(bool, const char*, const char*, const char*, uint64_t,
                                     const char*, mock_namespace_handle));
  MOCK_METHOD4(mock_link_namespaces,
               bool(bool, mock_namespace_handle, mock_namespace_handle, const char*));
  MOCK_METHOD2(mock_get_exported_namespace, mock_namespace_handle(bool, const char*));
  MOCK_METHOD4(mock_dlopen_ext, void*(bool, const char*, int, mock_namespace_handle));

  // Mocking libnativebridge APIs
  MOCK_METHOD0(NativeBridgeInitialized, bool());
  MOCK_METHOD0(NativeBridgeGetError, const char*());
  MOCK_METHOD1(NativeBridgeIsPathSupported, bool(const char*));
  MOCK_METHOD1(NativeBridgeIsSupported, bool(const char*));

  // Mocking "ClassLoader Object.getParent()"
  MOCK_METHOD1(JniObject_getParent, const char*(const char*));

 private:
  bool is_bridged_;
};

static std::unique_ptr<MockPlatform> mock;

// Provide C wrappers for the mock object.
extern "C" {
void* dlopen(const char* file, int flag) {
  return mock->dlopen(file, flag);
}

int dlclose(void* handle) {
  return mock->dlclose(handle);
}

char* dlerror(void) {
  return mock->dlerror();
}

bool android_init_anonymous_namespace(const char* sonames, const char* search_path) {
  return mock->mock_init_anonymous_namespace(false, sonames, search_path);
}

struct android_namespace_t* android_create_namespace(const char* name, const char* ld_library_path,
                                                     const char* default_library_path,
                                                     uint64_t type,
                                                     const char* permitted_when_isolated_path,
                                                     struct android_namespace_t* parent) {
  return TO_ANDROID_NAMESPACE(
      mock->mock_create_namespace(false, name, ld_library_path, default_library_path, type,
                                  permitted_when_isolated_path, TO_MOCK_NAMESPACE(parent)));
}

bool android_link_namespaces(struct android_namespace_t* from, struct android_namespace_t* to,
                             const char* sonames) {
  return mock->mock_link_namespaces(false, TO_MOCK_NAMESPACE(from), TO_MOCK_NAMESPACE(to), sonames);
}

struct android_namespace_t* android_get_exported_namespace(const char* name) {
  return TO_ANDROID_NAMESPACE(mock->mock_get_exported_namespace(false, name));
}

void* android_dlopen_ext(const char* filename, int flags, const android_dlextinfo* info) {
  return mock->mock_dlopen_ext(false, filename, flags, TO_MOCK_NAMESPACE(info->library_namespace));
}

// libnativebridge APIs
bool NativeBridgeIsSupported(const char* libpath) {
  return mock->NativeBridgeIsSupported(libpath);
}

struct native_bridge_namespace_t* NativeBridgeGetExportedNamespace(const char* name) {
  return TO_BRIDGED_NAMESPACE(mock->mock_get_exported_namespace(true, name));
}

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) {
  return TO_BRIDGED_NAMESPACE(
      mock->mock_create_namespace(true, name, ld_library_path, default_library_path, type,
                                  permitted_when_isolated_path, TO_MOCK_NAMESPACE(parent)));
}

bool NativeBridgeLinkNamespaces(struct native_bridge_namespace_t* from,
                                struct native_bridge_namespace_t* to, const char* sonames) {
  return mock->mock_link_namespaces(true, TO_MOCK_NAMESPACE(from), TO_MOCK_NAMESPACE(to), sonames);
}

void* NativeBridgeLoadLibraryExt(const char* libpath, int flag,
                                 struct native_bridge_namespace_t* ns) {
  return mock->mock_dlopen_ext(true, libpath, flag, TO_MOCK_NAMESPACE(ns));
}

bool NativeBridgeInitialized() {
  return mock->NativeBridgeInitialized();
}

bool NativeBridgeInitAnonymousNamespace(const char* public_ns_sonames,
                                        const char* anon_ns_library_path) {
  return mock->mock_init_anonymous_namespace(true, public_ns_sonames, anon_ns_library_path);
}

const char* NativeBridgeGetError() {
  return mock->NativeBridgeGetError();
}

bool NativeBridgeIsPathSupported(const char* path) {
  return mock->NativeBridgeIsPathSupported(path);
}

}  // extern "C"

// A very simple JNI mock.
// jstring is a pointer to utf8 char array. We don't need utf16 char here.
// jobject, jclass, and jmethodID are also a pointer to utf8 char array
// Only a few JNI methods that are actually used in libnativeloader are mocked.
JNINativeInterface* CreateJNINativeInterface() {
  JNINativeInterface* inf = new JNINativeInterface();
  memset(inf, 0, sizeof(JNINativeInterface));

  inf->GetStringUTFChars = [](JNIEnv*, jstring s, jboolean*) -> const char* {
    return reinterpret_cast<const char*>(s);
  };

  inf->ReleaseStringUTFChars = [](JNIEnv*, jstring, const char*) -> void { return; };

  inf->NewStringUTF = [](JNIEnv*, const char* bytes) -> jstring {
    return reinterpret_cast<jstring>(const_cast<char*>(bytes));
  };

  inf->FindClass = [](JNIEnv*, const char* name) -> jclass {
    return reinterpret_cast<jclass>(const_cast<char*>(name));
  };

  inf->CallObjectMethodV = [](JNIEnv*, jobject obj, jmethodID mid, va_list) -> jobject {
    if (strcmp("getParent", reinterpret_cast<const char*>(mid)) == 0) {
      // JniObject_getParent can be a valid jobject or nullptr if there is
      // no parent classloader.
      const char* ret = mock->JniObject_getParent(reinterpret_cast<const char*>(obj));
      return reinterpret_cast<jobject>(const_cast<char*>(ret));
    }
    return nullptr;
  };

  inf->GetMethodID = [](JNIEnv*, jclass, const char* name, const char*) -> jmethodID {
    return reinterpret_cast<jmethodID>(const_cast<char*>(name));
  };

  inf->NewWeakGlobalRef = [](JNIEnv*, jobject obj) -> jobject { return obj; };

  inf->IsSameObject = [](JNIEnv*, jobject a, jobject b) -> jboolean {
    return strcmp(reinterpret_cast<const char*>(a), reinterpret_cast<const char*>(b)) == 0;
  };

  return inf;
}

static void* const any_nonnull = reinterpret_cast<void*>(0x12345678);

// Custom matcher for comparing namespace handles
MATCHER_P(NsEq, other, "") {
  *result_listener << "comparing " << reinterpret_cast<const char*>(arg) << " and " << other;
  return strcmp(reinterpret_cast<const char*>(arg), reinterpret_cast<const char*>(other)) == 0;
}

/////////////////////////////////////////////////////////////////

// Test fixture
class NativeLoaderTest : public ::testing::TestWithParam<bool> {
 protected:
  bool IsBridged() { return GetParam(); }

  void SetUp() override {
    mock = std::make_unique<testing::NiceMock<MockPlatform>>(IsBridged());

    env = std::make_unique<JNIEnv>();
    env->functions = CreateJNINativeInterface();
  }

  void SetExpectations() {
    std::vector<std::string> default_public_libs =
        android::base::Split(preloadable_public_libraries(), ":");
    for (auto l : default_public_libs) {
      EXPECT_CALL(*mock, dlopen(StrEq(l.c_str()), RTLD_NOW | RTLD_NODELETE))
          .WillOnce(Return(any_nonnull));
    }
  }

  void RunTest() { InitializeNativeLoader(); }

  void TearDown() override {
    ResetNativeLoader();
    delete env->functions;
    mock.reset();
  }

  std::unique_ptr<JNIEnv> env;
};

/////////////////////////////////////////////////////////////////

TEST_P(NativeLoaderTest, InitializeLoadsDefaultPublicLibraries) {
  SetExpectations();
  RunTest();
}

INSTANTIATE_TEST_SUITE_P(NativeLoaderTests, NativeLoaderTest, testing::Bool());

/////////////////////////////////////////////////////////////////

class NativeLoaderTest_Create : public NativeLoaderTest {
 protected:
  // Test inputs (initialized to the default values). Overriding these
  // must be done before calling SetExpectations() and RunTest().
  uint32_t target_sdk_version = 29;
  std::string class_loader = "my_classloader";
  bool is_shared = false;
  std::string dex_path = "/data/app/foo/classes.dex";
  std::string library_path = "/data/app/foo/" LIB_DIR "/arm";
  std::string permitted_path = "/data/app/foo/" LIB_DIR;

  // expected output (.. for the default test inputs)
  std::string expected_namespace_name = "classloader-namespace";
  uint64_t expected_namespace_flags =
      ANDROID_NAMESPACE_TYPE_ISOLATED | ANDROID_NAMESPACE_TYPE_ALSO_USED_AS_ANONYMOUS;
  std::string expected_library_path = library_path;
  std::string expected_permitted_path = std::string("/data:/mnt/expand:") + permitted_path;
  std::string expected_parent_namespace = "system";
  bool expected_link_with_platform_ns = true;
  bool expected_link_with_art_ns = true;
  bool expected_link_with_sphal_ns = !vendor_public_libraries().empty();
  bool expected_link_with_vndk_ns = false;
  bool expected_link_with_default_ns = false;
  bool expected_link_with_neuralnetworks_ns = true;
  bool expected_link_with_cronet_ns = true;
  std::string expected_shared_libs_to_platform_ns = default_public_libraries();
  std::string expected_shared_libs_to_art_ns = art_public_libraries();
  std::string expected_shared_libs_to_sphal_ns = vendor_public_libraries();
  std::string expected_shared_libs_to_vndk_ns = vndksp_libraries();
  std::string expected_shared_libs_to_default_ns = default_public_libraries();
  std::string expected_shared_libs_to_neuralnetworks_ns = neuralnetworks_public_libraries();
  std::string expected_shared_libs_to_cronet_ns = cronet_public_libraries();

  void SetExpectations() {
    NativeLoaderTest::SetExpectations();

    ON_CALL(*mock, JniObject_getParent(StrEq(class_loader))).WillByDefault(Return(nullptr));

    EXPECT_CALL(*mock, NativeBridgeIsPathSupported(_)).Times(testing::AnyNumber());
    EXPECT_CALL(*mock, NativeBridgeInitialized()).Times(testing::AnyNumber());

    EXPECT_CALL(*mock, mock_create_namespace(
                           Eq(IsBridged()), StrEq(expected_namespace_name), nullptr,
                           StrEq(expected_library_path), expected_namespace_flags,
                           StrEq(expected_permitted_path), NsEq(expected_parent_namespace.c_str())))
        .WillOnce(Return(TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE(dex_path.c_str()))));
    if (expected_link_with_platform_ns) {
      EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("system"),
                                              StrEq(expected_shared_libs_to_platform_ns)))
          .WillOnce(Return(true));
    }
    if (expected_link_with_art_ns) {
      EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("art"),
                                              StrEq(expected_shared_libs_to_art_ns)))
          .WillOnce(Return(true));
    }
    if (expected_link_with_sphal_ns) {
      EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("sphal"),
                                              StrEq(expected_shared_libs_to_sphal_ns)))
          .WillOnce(Return(true));
    }
    if (expected_link_with_vndk_ns) {
      EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("vndk"),
                                              StrEq(expected_shared_libs_to_vndk_ns)))
          .WillOnce(Return(true));
    }
    if (expected_link_with_default_ns) {
      EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("default"),
                                              StrEq(expected_shared_libs_to_default_ns)))
          .WillOnce(Return(true));
    }
    if (expected_link_with_neuralnetworks_ns) {
      EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("neuralnetworks"),
                                              StrEq(expected_shared_libs_to_neuralnetworks_ns)))
          .WillOnce(Return(true));
    }
    if (expected_link_with_cronet_ns) {
      EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), _, NsEq("cronet"),
                                              StrEq(expected_shared_libs_to_cronet_ns)))
          .WillOnce(Return(true));
    }
  }

  void RunTest() {
    NativeLoaderTest::RunTest();

    jstring err = CreateClassLoaderNamespace(
        env(), target_sdk_version, env()->NewStringUTF(class_loader.c_str()), is_shared,
        env()->NewStringUTF(dex_path.c_str()), env()->NewStringUTF(library_path.c_str()),
        env()->NewStringUTF(permitted_path.c_str()));

    // no error
    EXPECT_EQ(err, nullptr) << "Error is: " << std::string(ScopedUtfChars(env(), err).c_str());

    if (!IsBridged()) {
      struct android_namespace_t* ns =
          FindNamespaceByClassLoader(env(), env()->NewStringUTF(class_loader.c_str()));

      // The created namespace is for this apk
      EXPECT_EQ(dex_path.c_str(), reinterpret_cast<const char*>(ns));
    } else {
      struct NativeLoaderNamespace* ns =
          FindNativeLoaderNamespaceByClassLoader(env(), env()->NewStringUTF(class_loader.c_str()));

      // The created namespace is for the this apk
      EXPECT_STREQ(dex_path.c_str(),
                   reinterpret_cast<const char*>(ns->ToRawNativeBridgeNamespace()));
    }
  }

  JNIEnv* env() { return NativeLoaderTest::env.get(); }
};

TEST_P(NativeLoaderTest_Create, DownloadedApp) {
  SetExpectations();
  RunTest();
}

TEST_P(NativeLoaderTest_Create, BundledSystemApp) {
  dex_path = "/system/app/foo/foo.apk";
  is_shared = true;

  expected_namespace_name = "classloader-namespace-shared";
  expected_namespace_flags |= ANDROID_NAMESPACE_TYPE_SHARED;
  SetExpectations();
  RunTest();
}

TEST_P(NativeLoaderTest_Create, BundledVendorApp) {
  dex_path = "/vendor/app/foo/foo.apk";
  is_shared = true;

  expected_namespace_name = "classloader-namespace-shared";
  expected_namespace_flags |= ANDROID_NAMESPACE_TYPE_SHARED;
  SetExpectations();
  RunTest();
}

TEST_P(NativeLoaderTest_Create, UnbundledVendorApp) {
  dex_path = "/vendor/app/foo/foo.apk";
  is_shared = false;

  expected_namespace_name = "vendor-classloader-namespace";
  expected_library_path = expected_library_path + ":/vendor/" LIB_DIR;
  expected_permitted_path = expected_permitted_path + ":/vendor/" LIB_DIR;
  expected_shared_libs_to_platform_ns =
      expected_shared_libs_to_platform_ns + ":" + llndk_libraries();
  expected_link_with_vndk_ns = true;
  SetExpectations();
  RunTest();
}

TEST_P(NativeLoaderTest_Create, BundledProductApp) {
  dex_path = "/product/app/foo/foo.apk";
  is_shared = true;

  expected_namespace_name = "classloader-namespace-shared";
  expected_namespace_flags |= ANDROID_NAMESPACE_TYPE_SHARED;
  SetExpectations();
  RunTest();
}

TEST_P(NativeLoaderTest_Create, UnbundledProductApp) {
  dex_path = "/product/app/foo/foo.apk";
  is_shared = false;

  if (is_product_vndk_version_defined()) {
    expected_namespace_name = "vendor-classloader-namespace";
    expected_library_path = expected_library_path + ":/product/" LIB_DIR ":/system/product/" LIB_DIR;
    expected_permitted_path =
        expected_permitted_path + ":/product/" LIB_DIR ":/system/product/" LIB_DIR;
    expected_shared_libs_to_platform_ns =
        expected_shared_libs_to_platform_ns + ":" + llndk_libraries();
    expected_link_with_vndk_ns = true;
  }
  SetExpectations();
  RunTest();
}

TEST_P(NativeLoaderTest_Create, NamespaceForSharedLibIsNotUsedAsAnonymousNamespace) {
  if (IsBridged()) {
    // There is no shared lib in translated arch
    // TODO(jiyong): revisit this
    return;
  }
  // compared to apks, for java shared libs, library_path is empty; java shared
  // libs don't have their own native libs. They use platform's.
  library_path = "";
  expected_library_path = library_path;
  // no ALSO_USED_AS_ANONYMOUS
  expected_namespace_flags = ANDROID_NAMESPACE_TYPE_ISOLATED;
  SetExpectations();
  RunTest();
}

TEST_P(NativeLoaderTest_Create, TwoApks) {
  SetExpectations();
  const uint32_t second_app_target_sdk_version = 29;
  const std::string second_app_class_loader = "second_app_classloader";
  const bool second_app_is_shared = false;
  const std::string second_app_dex_path = "/data/app/bar/classes.dex";
  const std::string second_app_library_path = "/data/app/bar/" LIB_DIR "/arm";
  const std::string second_app_permitted_path = "/data/app/bar/" LIB_DIR;
  const std::string expected_second_app_permitted_path =
      std::string("/data:/mnt/expand:") + second_app_permitted_path;
  const std::string expected_second_app_parent_namespace = "classloader-namespace";
  // no ALSO_USED_AS_ANONYMOUS
  const uint64_t expected_second_namespace_flags = ANDROID_NAMESPACE_TYPE_ISOLATED;

  // The scenario is that second app is loaded by the first app.
  // So the first app's classloader (`classloader`) is parent of the second
  // app's classloader.
  ON_CALL(*mock, JniObject_getParent(StrEq(second_app_class_loader)))
      .WillByDefault(Return(class_loader.c_str()));

  // namespace for the second app is created. Its parent is set to the namespace
  // of the first app.
  EXPECT_CALL(*mock, mock_create_namespace(
                         Eq(IsBridged()), StrEq(expected_namespace_name), nullptr,
                         StrEq(second_app_library_path), expected_second_namespace_flags,
                         StrEq(expected_second_app_permitted_path), NsEq(dex_path.c_str())))
      .WillOnce(Return(TO_MOCK_NAMESPACE(TO_ANDROID_NAMESPACE(second_app_dex_path.c_str()))));
  EXPECT_CALL(*mock, mock_link_namespaces(Eq(IsBridged()), NsEq(second_app_dex_path.c_str()), _, _))
      .WillRepeatedly(Return(true));

  RunTest();
  jstring err = CreateClassLoaderNamespace(
      env(), second_app_target_sdk_version, env()->NewStringUTF(second_app_class_loader.c_str()),
      second_app_is_shared, env()->NewStringUTF(second_app_dex_path.c_str()),
      env()->NewStringUTF(second_app_library_path.c_str()),
      env()->NewStringUTF(second_app_permitted_path.c_str()));

  // success
  EXPECT_EQ(err, nullptr) << "Error is: " << std::string(ScopedUtfChars(env(), err).c_str());

  if (!IsBridged()) {
    struct android_namespace_t* ns =
        FindNamespaceByClassLoader(env(), env()->NewStringUTF(second_app_class_loader.c_str()));

    // The created namespace is for the second apk
    EXPECT_EQ(second_app_dex_path.c_str(), reinterpret_cast<const char*>(ns));
  } else {
    struct NativeLoaderNamespace* ns = FindNativeLoaderNamespaceByClassLoader(
        env(), env()->NewStringUTF(second_app_class_loader.c_str()));

    // The created namespace is for the second apk
    EXPECT_STREQ(second_app_dex_path.c_str(),
                 reinterpret_cast<const char*>(ns->ToRawNativeBridgeNamespace()));
  }
}

INSTANTIATE_TEST_SUITE_P(NativeLoaderTests_Create, NativeLoaderTest_Create, testing::Bool());

const std::function<Result<bool>(const struct ConfigEntry&)> always_true =
    [](const struct ConfigEntry&) -> Result<bool> { return true; };

TEST(NativeLoaderConfigParser, NamesAndComments) {
  const char file_content[] = R"(
######

libA.so
#libB.so


      libC.so
libD.so
    #### libE.so
)";
  const std::vector<std::string> expected_result = {"libA.so", "libC.so", "libD.so"};
  Result<std::vector<std::string>> result = ParseConfig(file_content, always_true);
  ASSERT_TRUE(result) << result.error().message();
  ASSERT_EQ(expected_result, *result);
}

TEST(NativeLoaderConfigParser, WithBitness) {
  const char file_content[] = R"(
libA.so 32
libB.so 64
libC.so
)";
#if defined(__LP64__)
  const std::vector<std::string> expected_result = {"libB.so", "libC.so"};
#else
  const std::vector<std::string> expected_result = {"libA.so", "libC.so"};
#endif
  Result<std::vector<std::string>> result = ParseConfig(file_content, always_true);
  ASSERT_TRUE(result) << result.error().message();
  ASSERT_EQ(expected_result, *result);
}

TEST(NativeLoaderConfigParser, WithNoPreload) {
  const char file_content[] = R"(
libA.so nopreload
libB.so nopreload
libC.so
)";

  const std::vector<std::string> expected_result = {"libC.so"};
  Result<std::vector<std::string>> result =
      ParseConfig(file_content,
                  [](const struct ConfigEntry& entry) -> Result<bool> { return !entry.nopreload; });
  ASSERT_TRUE(result) << result.error().message();
  ASSERT_EQ(expected_result, *result);
}

TEST(NativeLoaderConfigParser, WithNoPreloadAndBitness) {
  const char file_content[] = R"(
libA.so nopreload 32
libB.so 64 nopreload
libC.so 32
libD.so 64
libE.so nopreload
)";

#if defined(__LP64__)
  const std::vector<std::string> expected_result = {"libD.so"};
#else
  const std::vector<std::string> expected_result = {"libC.so"};
#endif
  Result<std::vector<std::string>> result =
      ParseConfig(file_content,
                  [](const struct ConfigEntry& entry) -> Result<bool> { return !entry.nopreload; });
  ASSERT_TRUE(result) << result.error().message();
  ASSERT_EQ(expected_result, *result);
}

TEST(NativeLoaderConfigParser, RejectMalformed) {
  ASSERT_FALSE(ParseConfig("libA.so 32 64", always_true));
  ASSERT_FALSE(ParseConfig("libA.so 32 32", always_true));
  ASSERT_FALSE(ParseConfig("libA.so 32 nopreload 64", always_true));
  ASSERT_FALSE(ParseConfig("32 libA.so nopreload", always_true));
  ASSERT_FALSE(ParseConfig("nopreload libA.so 32", always_true));
  ASSERT_FALSE(ParseConfig("libA.so nopreload # comment", always_true));
}

}  // namespace nativeloader
}  // namespace android
