// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <fcntl.h>
#include <inttypes.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fdio/io.h>
#include <lib/zx/status.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <zircon/dlfcn.h>
#include <zircon/processargs.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>

#include <zxtest/zxtest.h>

#include "src/lib/loader_service/loader_service.h"

#ifndef LIBPREFIX
#error "BUILD.gn should define LIBPREFIX"
#endif

zx_status_t load_vmo(const char* filename, zx_handle_t* out) {
  int fd = open(filename, O_RDONLY);
  if (fd < 0)
    return ZX_ERR_IO;
  zx_handle_t vmo;
  zx_handle_t exec_vmo;
  zx_status_t status = fdio_get_vmo_clone(fd, &vmo);
  close(fd);

  if (status != ZX_OK) {
    return status;
  }

  status = zx_vmo_replace_as_executable(vmo, ZX_HANDLE_INVALID, &exec_vmo);
  if (status != ZX_OK) {
    return status;
  }

  if (strlen(filename) >= ZX_MAX_NAME_LEN) {
    const char* p = strrchr(filename, '/');
    if (p != NULL) {
      filename = p + 1;
    }
  }

  status = zx_object_set_property(exec_vmo, ZX_PROP_NAME, filename, strlen(filename));
  if (status != ZX_OK) {
    zx_handle_close(exec_vmo);
    return status;
  }

  *out = exec_vmo;
  return ZX_OK;
}

TEST(DlfcnTests, dlopen_vmo_test) {
  zx_handle_t vmo = ZX_HANDLE_INVALID;
  zx_status_t status = load_vmo(LIBPREFIX "libtrace-engine.so", &vmo);
  EXPECT_EQ(status, ZX_OK, "");
  EXPECT_NE(vmo, ZX_HANDLE_INVALID, "load_vmo");

  void* obj = dlopen_vmo(vmo, RTLD_LOCAL);
  EXPECT_NOT_NULL(obj, "dlopen_vmo");

  zx_handle_close(vmo);

  void* sym = dlsym(obj, "trace_engine_initialize");
  EXPECT_NOT_NULL(sym, "dlsym");

  int ok = dlclose(obj);
  EXPECT_EQ(ok, 0, "dlclose");
}

// This should be some library that this program links against.
#define TEST_SONAME "libfdio.so"
#define TEST_NAME "foobar"
#define TEST_ACTUAL_NAME LIBPREFIX TEST_SONAME

class TestLoaderService : public loader::LoaderServiceBase {
 public:
  static std::shared_ptr<TestLoaderService> Create(async_dispatcher_t* dispatcher) {
    // Can't use make_shared because constructor is private
    return std::shared_ptr<TestLoaderService>(new TestLoaderService(dispatcher));
  }

  int load_object_calls() { return load_object_calls_; }
  int load_object_success() { return load_object_success_; }

 private:
  TestLoaderService(async_dispatcher_t* dispatcher) : LoaderServiceBase(dispatcher, "dlfcn_test") {}

  virtual zx::status<zx::vmo> LoadObjectImpl(std::string name) override {
    ++load_object_calls_;

    if (name != TEST_NAME) {
      printf("loader saw \"%s\", expected \"%s\"", name.c_str(), TEST_NAME);
      return zx::error(ZX_ERR_NOT_FOUND);
    }

    zx::vmo vmo;
    zx_status_t status = load_vmo(TEST_ACTUAL_NAME, vmo.reset_and_get_address());
    if (status != ZX_OK) {
      return zx::error(status);
    }
    ++load_object_success_;
    return zx::ok(std::move(vmo));
  }

  int load_object_calls_ = 0;
  int load_object_success_ = 0;
};

static void show_dlerror(void) { printf("dlerror: %s\n", dlerror()); }

TEST(DlfcnTests, loader_service_test) {
  // Get a handle to an existing library with a known SONAME.
  void* by_name = dlopen(TEST_SONAME, RTLD_NOLOAD);
  EXPECT_NOT_NULL(by_name, "dlopen failed on " TEST_SONAME);
  if (by_name == NULL)
    show_dlerror();

  // Spin up our test service.
  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  ASSERT_OK(loop.StartThread());
  auto loader = TestLoaderService::Create(loop.dispatcher());
  auto loader_conn = loader->Connect();
  ASSERT_OK(loader_conn.status_value());

  // Install the service.
  zx_handle_t old = dl_set_loader_service(loader_conn->TakeChannel().release());
  EXPECT_NE(old, ZX_HANDLE_INVALID, "dl_set_loader_service");

  // Now to a lookup that should go through our service.  It
  // should load up the new copy of the file, find that its
  // SONAME matches an existing library, and just return it.
  void* via_service = dlopen(TEST_NAME, RTLD_LOCAL);

  EXPECT_NOT_NULL(via_service, "dlopen via service");
  if (via_service == NULL) {
    show_dlerror();
  }
  EXPECT_EQ(loader->load_object_calls(), 1, "loader-service not called exactly once");
  EXPECT_EQ(loader->load_object_success(), 1, "loader service call didn't succeed");

  // It should not just have succeeded, but gotten the very
  // same handle as the by-name lookup.
  EXPECT_TRUE(via_service == by_name, "dlopen via service");

  int fail = dlclose(by_name);
  EXPECT_EQ(fail, 0, "dlclose on by-name");
  if (fail)
    show_dlerror();

  fail = dlclose(via_service);
  EXPECT_EQ(fail, 0, "dlclose on via-service");
  if (fail)
    show_dlerror();

  // Put things back to how they were.
  zx_handle_t old2 = dl_set_loader_service(old);
  zx_handle_close(old2);
}

TEST(DlfcnTests, clone_test) {
  zx_handle_t h = ZX_HANDLE_INVALID;
  zx_status_t s = dl_clone_loader_service(&h);
  EXPECT_EQ(s, ZX_OK, "%s", zx_status_get_string(s));
  EXPECT_NE(h, ZX_HANDLE_INVALID, "invalid handle from loader service");

  zx_handle_close(h);
}

void test_global_function(void) {}

TEST(DlfcnTests, dladdr_unexported_test) {
  Dl_info info;
  ASSERT_NE(dladdr((void*)&test_global_function, &info), 0, "dladdr failed");

  // This symbol is not exported to .dynsym, so it won't be found.
  EXPECT_NULL(info.dli_sname, "unexpected symbol name");
  EXPECT_NULL(info.dli_saddr, "unexpected symbol address");
}

// TODO(dbort): Test that this process uses the system loader service by default

TEST(DlfcnTests, dso_no_note_test) {
  void* obj = dlopen("test-dso-no-note.so", RTLD_LOCAL);
  ASSERT_NOT_NULL(obj, "%s", dlerror());

  void* sym = dlsym(obj, "dummy");
  EXPECT_NOT_NULL(sym, "%s", dlerror());

  (*(void (*)(void))(uintptr_t)(sym))();

  EXPECT_EQ(dlclose(obj), 0, "%s", dlerror());
}
