// Copyright 2019 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 <fuchsia/device/c/fidl.h>
#include <fuchsia/device/test/c/fidl.h>
#include <lib/devmgr-integration-test/fixture.h>
#include <lib/driver-integration-test/fixture.h>
#include <lib/fdio/fdio.h>
#include <lib/zx/channel.h>
#include <lib/zx/vmo.h>
#include <limits.h>

#include <ddk/metadata/test.h>
#include <ddk/platform-defs.h>
#include <zxtest/zxtest.h>

namespace {

using devmgr_integration_test::IsolatedDevmgr;

static constexpr const char kDevPrefix[] = "/dev/";
static constexpr const char kDriverTestDir[] = "/boot/driver/test";
static constexpr const char kPassDriverName[] = "unit-test-pass.so";
static constexpr const char kFailDriverName[] = "unit-test-fail.so";

zx_status_t GetArguments(const fbl::Vector<const char*>& arguments, zx::vmo* out,
                         uint32_t* length) {
  size_t size = 0;
  for (const char* arg : arguments) {
    // Add 1 for the null byte.
    size += strlen(arg) + 1;
  }

  zx::vmo vmo;
  zx_status_t status = zx::vmo::create(size, 0, &vmo);
  size_t offset = 0;
  for (const char* arg : arguments) {
    // Add 1 for the null byte.
    size_t length = strlen(arg) + 1;
    status = vmo.write(arg, offset, length);
    if (status != ZX_OK) {
      return status;
    }
    offset += length;
  }

  *length = static_cast<uint32_t>(size);
  *out = std::move(vmo);
  return status;
}

void CreateTestDevice(const IsolatedDevmgr& devmgr, const char* driver_name,
                      zx::channel* dev_channel) {
  fbl::unique_fd root_fd;
  zx_status_t status =
      devmgr_integration_test::RecursiveWaitForFile(devmgr.devfs_root(), "test/test", &root_fd);
  ASSERT_OK(status);

  zx::channel test_root;
  status = fdio_get_service_handle(root_fd.release(), test_root.reset_and_get_address());
  ASSERT_OK(status);

  char devpath[fuchsia_device_test_MAX_DEVICE_PATH_LEN + 1];
  size_t devpath_count;
  zx_status_t call_status;
  status = fuchsia_device_test_RootDeviceCreateDevice(test_root.get(), driver_name,
                                                      strlen(driver_name), &call_status, devpath,
                                                      sizeof(devpath) - 1, &devpath_count);
  ASSERT_OK(status);
  ASSERT_OK(call_status);
  devpath[devpath_count] = 0;
  ASSERT_STR_NE(devpath, kDevPrefix);

  const char* relative_devpath = devpath + strlen(kDevPrefix);
  fbl::unique_fd fd;
  status =
      devmgr_integration_test::RecursiveWaitForFile(devmgr.devfs_root(), relative_devpath, &fd);
  ASSERT_OK(status);

  status = fdio_get_service_handle(fd.release(), dev_channel->reset_and_get_address());
  ASSERT_OK(status);
}

// Test binding second time
TEST(DeviceControllerIntegrationTest, TestDuplicateBindSameDriver) {
  IsolatedDevmgr devmgr;
  auto args = IsolatedDevmgr::DefaultArgs();

  zx_status_t status = IsolatedDevmgr::Create(std::move(args), &devmgr);
  ASSERT_OK(status);

  zx::channel dev_channel;
  CreateTestDevice(devmgr, kPassDriverName, &dev_channel);

  char libpath[PATH_MAX];
  int len = snprintf(libpath, sizeof(libpath), "%s/%s", kDriverTestDir, kPassDriverName);
  zx_status_t call_status;
  status = fuchsia_device_ControllerBind(dev_channel.get(), libpath, len, &call_status);
  ASSERT_OK(status);
  ASSERT_OK(call_status);

  status = fuchsia_device_ControllerBind(dev_channel.get(), libpath, len, &call_status);
  ASSERT_OK(status);
  ASSERT_EQ(call_status, ZX_ERR_ALREADY_BOUND);

  fuchsia_device_test_DeviceDestroy(dev_channel.get());
}

TEST(DeviceControllerIntegrationTest, TestRebindNoChildrenManualBind) {
  IsolatedDevmgr devmgr;
  auto args = IsolatedDevmgr::DefaultArgs();

  zx_status_t status = IsolatedDevmgr::Create(std::move(args), &devmgr);
  ASSERT_OK(status);

  zx::channel dev_channel;
  CreateTestDevice(devmgr, kPassDriverName, &dev_channel);

  char libpath[PATH_MAX];
  int len = snprintf(libpath, sizeof(libpath), "%s/%s", kDriverTestDir, kPassDriverName);
  zx_status_t call_status = ZX_OK;
  status = fuchsia_device_ControllerRebind(dev_channel.get(), libpath, len, &call_status);
  ASSERT_OK(status);
  ASSERT_OK(call_status);

  fuchsia_device_test_DeviceDestroy(dev_channel.get());
}

TEST(DeviceControllerIntegrationTest, TestRebindChildrenAutoBind) {
  using driver_integration_test::IsolatedDevmgr;
  driver_integration_test::IsolatedDevmgr::Args args;
  driver_integration_test::IsolatedDevmgr devmgr;

  board_test::DeviceEntry dev = {};
  dev.vid = PDEV_VID_TEST;
  dev.pid = PDEV_PID_DEVHOST_TEST;
  dev.did = 0;
  args.device_list.push_back(dev);

  zx_status_t status = IsolatedDevmgr::Create(&args, &devmgr);
  ASSERT_OK(status);

  fbl::unique_fd test_fd, parent_fd, child_fd;
  zx::channel parent_channel;
  status = devmgr_integration_test::RecursiveWaitForFile(devmgr.devfs_root(),
                                                         "sys/platform/11:0e:0", &test_fd);
  status = devmgr_integration_test::RecursiveWaitForFile(
      devmgr.devfs_root(), "sys/platform/11:0e:0/devhost-test-parent", &parent_fd);

  ASSERT_OK(status);
  status = fdio_get_service_handle(parent_fd.release(), parent_channel.reset_and_get_address());
  ASSERT_OK(status);

  zx_status_t call_status = ZX_OK;
  // Do not open the child. Otherwise rebind will be stuck.
  status = fuchsia_device_ControllerRebind(parent_channel.get(), "", 0, &call_status);
  ASSERT_OK(status);
  ASSERT_OK(call_status);

  ASSERT_OK(devmgr_integration_test::RecursiveWaitForFile(
      devmgr.devfs_root(), "sys/platform/11:0e:0/devhost-test-parent", &parent_fd));
  ASSERT_OK(devmgr_integration_test::RecursiveWaitForFile(
      devmgr.devfs_root(), "sys/platform/11:0e:0/devhost-test-parent/devhost-test-child",
      &child_fd));
}

TEST(DeviceControllerIntegrationTest, TestRebindChildrenManualBind) {
  using driver_integration_test::IsolatedDevmgr;
  driver_integration_test::IsolatedDevmgr::Args args;
  driver_integration_test::IsolatedDevmgr devmgr;

  board_test::DeviceEntry dev = {};
  dev.vid = PDEV_VID_TEST;
  dev.pid = PDEV_PID_DEVHOST_TEST;
  dev.did = 0;
  args.device_list.push_back(dev);

  ASSERT_OK(IsolatedDevmgr::Create(&args, &devmgr));

  fbl::unique_fd test_fd, parent_fd, child_fd;
  zx::channel parent_channel;
  ASSERT_OK(devmgr_integration_test::RecursiveWaitForFile(devmgr.devfs_root(),
                                                          "sys/platform/11:0e:0", &test_fd));
  ASSERT_OK(devmgr_integration_test::RecursiveWaitForFile(
      devmgr.devfs_root(), "sys/platform/11:0e:0/devhost-test-parent", &parent_fd));
  ASSERT_OK(fdio_get_service_handle(parent_fd.release(), parent_channel.reset_and_get_address()));

  zx_status_t call_status = ZX_OK;
  char libpath[PATH_MAX];
  int len = snprintf(libpath, sizeof(libpath), "%s/%s", "/boot/driver", "devhost-test-child.so");
  // Do not open the child. Otherwise rebind will be stuck.
  ASSERT_OK(fuchsia_device_ControllerRebind(parent_channel.get(), libpath, len, &call_status));
  ASSERT_OK(call_status);

  ASSERT_OK(devmgr_integration_test::RecursiveWaitForFile(
      devmgr.devfs_root(), "sys/platform/11:0e:0/devhost-test-parent", &parent_fd));
  ASSERT_OK(devmgr_integration_test::RecursiveWaitForFile(
      devmgr.devfs_root(), "sys/platform/11:0e:0/devhost-test-parent/devhost-test-child",
      &child_fd));
}

// Test binding again, but with different driver
TEST(DeviceControllerIntegrationTest, TestDuplicateBindDifferentDriver) {
  IsolatedDevmgr devmgr;
  auto args = IsolatedDevmgr::DefaultArgs();

  zx_status_t status = IsolatedDevmgr::Create(std::move(args), &devmgr);
  ASSERT_OK(status);

  zx::channel dev_channel;
  CreateTestDevice(devmgr, kPassDriverName, &dev_channel);

  char libpath[PATH_MAX];
  int len = snprintf(libpath, sizeof(libpath), "%s/%s", kDriverTestDir, kPassDriverName);
  zx_status_t call_status;
  status = fuchsia_device_ControllerBind(dev_channel.get(), libpath, len, &call_status);
  ASSERT_OK(status);
  ASSERT_OK(call_status);

  len = snprintf(libpath, sizeof(libpath), "%s/%s", kDriverTestDir, kFailDriverName);
  status = fuchsia_device_ControllerBind(dev_channel.get(), libpath, len, &call_status);
  ASSERT_OK(status);
  ASSERT_EQ(call_status, ZX_ERR_ALREADY_BOUND);

  fuchsia_device_test_DeviceDestroy(dev_channel.get());
}

TEST(DeviceControllerIntegrationTest, AllTestsEnabledBind) {
  IsolatedDevmgr devmgr;
  auto args = IsolatedDevmgr::DefaultArgs();

  fbl::Vector<const char*> arguments;
  arguments.push_back("driver.tests.enable=true");
  args.get_arguments = [&arguments](zx::vmo* out, uint32_t* length) {
    return GetArguments(arguments, out, length);
  };

  zx_status_t status = IsolatedDevmgr::Create(std::move(args), &devmgr);
  ASSERT_OK(status);

  zx::channel dev_channel;
  CreateTestDevice(devmgr, kPassDriverName, &dev_channel);

  char libpath[PATH_MAX];
  int len = snprintf(libpath, sizeof(libpath), "%s/%s", kDriverTestDir, kPassDriverName);
  zx_status_t call_status;
  status = fuchsia_device_ControllerBind(dev_channel.get(), libpath, len, &call_status);
  ASSERT_OK(status);
  ASSERT_OK(call_status);

  fuchsia_device_test_DeviceDestroy(dev_channel.get());
}

TEST(DeviceControllerIntegrationTest, AllTestsEnabledBindFail) {
  IsolatedDevmgr devmgr;
  auto args = IsolatedDevmgr::DefaultArgs();

  fbl::Vector<const char*> arguments;
  arguments.push_back("driver.tests.enable=true");
  args.get_arguments = [&arguments](zx::vmo* out, uint32_t* length) {
    return GetArguments(arguments, out, length);
  };

  zx_status_t status = IsolatedDevmgr::Create(std::move(args), &devmgr);
  ASSERT_OK(status);

  zx::channel dev_channel;
  CreateTestDevice(devmgr, kFailDriverName, &dev_channel);

  char libpath[PATH_MAX];
  int len = snprintf(libpath, sizeof(libpath), "%s/%s", kDriverTestDir, kFailDriverName);
  zx_status_t call_status;
  status = fuchsia_device_ControllerBind(dev_channel.get(), libpath, len, &call_status);
  ASSERT_OK(status);
  ASSERT_EQ(ZX_ERR_BAD_STATE, call_status);

  fuchsia_device_test_DeviceDestroy(dev_channel.get());
}

// Test the flag using bind failure as a proxy for "the unit test did run".
TEST(DeviceControllerIntegrationTest, SpecificTestEnabledBindFail) {
  IsolatedDevmgr devmgr;
  auto args = IsolatedDevmgr::DefaultArgs();

  fbl::Vector<const char*> arguments;
  arguments.push_back("driver.unit_test_fail.tests.enable=true");
  args.get_arguments = [&arguments](zx::vmo* out, uint32_t* length) {
    return GetArguments(arguments, out, length);
  };

  zx_status_t status = IsolatedDevmgr::Create(std::move(args), &devmgr);
  ASSERT_OK(status);

  zx::channel dev_channel;
  CreateTestDevice(devmgr, kFailDriverName, &dev_channel);

  char libpath[PATH_MAX];
  int len = snprintf(libpath, sizeof(libpath), "%s/%s", kDriverTestDir, kFailDriverName);
  zx_status_t call_status;
  status = fuchsia_device_ControllerBind(dev_channel.get(), libpath, len, &call_status);
  ASSERT_OK(status);
  ASSERT_EQ(ZX_ERR_BAD_STATE, call_status);

  fuchsia_device_test_DeviceDestroy(dev_channel.get());
}

// Test the flag using bind success as a proxy for "the unit test didn't run".
TEST(DeviceControllerIntegrationTest, DefaultTestsDisabledBind) {
  IsolatedDevmgr devmgr;
  auto args = IsolatedDevmgr::DefaultArgs();

  zx_status_t status = IsolatedDevmgr::Create(std::move(args), &devmgr);
  ASSERT_OK(status);

  zx::channel dev_channel;
  CreateTestDevice(devmgr, kFailDriverName, &dev_channel);

  char libpath[PATH_MAX];
  int len = snprintf(libpath, sizeof(libpath), "%s/%s", kDriverTestDir, kFailDriverName);
  zx_status_t call_status;
  status = fuchsia_device_ControllerBind(dev_channel.get(), libpath, len, &call_status);
  ASSERT_OK(status);
  ASSERT_OK(call_status);

  fuchsia_device_test_DeviceDestroy(dev_channel.get());
}

// Test the flag using bind success as a proxy for "the unit test didn't run".
TEST(DeviceControllerIntegrationTest, SpecificTestDisabledBind) {
  IsolatedDevmgr devmgr;
  auto args = IsolatedDevmgr::DefaultArgs();

  fbl::Vector<const char*> arguments;
  arguments.push_back("driver.tests.enable=true");
  arguments.push_back("driver.unit_test_fail.tests.enable=false");
  args.get_arguments = [&arguments](zx::vmo* out, uint32_t* length) {
    return GetArguments(arguments, out, length);
  };

  zx_status_t status = IsolatedDevmgr::Create(std::move(args), &devmgr);
  ASSERT_OK(status);

  zx::channel dev_channel;
  CreateTestDevice(devmgr, kFailDriverName, &dev_channel);

  char libpath[PATH_MAX];
  int len = snprintf(libpath, sizeof(libpath), "%s/%s", kDriverTestDir, kFailDriverName);
  zx_status_t call_status;
  status = fuchsia_device_ControllerBind(dev_channel.get(), libpath, len, &call_status);
  ASSERT_OK(status);
  ASSERT_OK(call_status);

  fuchsia_device_test_DeviceDestroy(dev_channel.get());
}

}  // namespace
