// 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/hardware/ethertap/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
#include <fuchsia/virtualaudio/cpp/fidl.h>
#include <lib/devmgr-integration-test/fixture.h>
#include <lib/fdio/directory.h>
#include <lib/gtest/real_loop_fixture.h>
#include <lib/sys/cpp/component_context.h>
#include <zircon/device/vfs.h>

#include <ddk/platform-defs.h>

#include "isolated_devmgr.h"
#include "src/lib/files/glob.h"

namespace isolated_devmgr {
namespace testing {

class DevmgrTest : public ::gtest::RealLoopFixture {
 protected:
  static constexpr const char* kSysdevDriver = "/boot/driver/test/sysdev.so";
  static constexpr const char* kPlatformDriver = "/boot/driver/platform-bus.so";
  const board_test::DeviceEntry kRtcDeviceEntry = []() {
    board_test::DeviceEntry entry = {};
    strcpy(entry.name, "fallback-rtc");
    entry.vid = PDEV_VID_GENERIC;
    entry.pid = PDEV_PID_GENERIC;
    entry.did = PDEV_DID_RTC_FALLBACK;
    return entry;
  }();

  const board_test::DeviceEntry kCrashDeviceEntry = []() {
    board_test::DeviceEntry entry = {};
    strcpy(entry.name, "crash-device");
    entry.vid = PDEV_VID_TEST;
    entry.pid = PDEV_PID_GENERIC;
    entry.did = PDEV_DID_TEST_CRASH;
    return entry;
  }();

  std::unique_ptr<IsolatedDevmgr> CreateDevmgrSysdev() {
    devmgr_launcher::Args args;
    IsolatedDevmgr::ExtraArgs extra_args;
    args.sys_device_driver = kSysdevDriver;

    args.stdio = fbl::unique_fd(open("/dev/null", O_RDWR));
    args.load_drivers.push_back("/boot/driver/ethernet.so");
    args.load_drivers.push_back("/boot/driver/ethertap.so");
    args.disable_block_watcher = true;
    return IsolatedDevmgr::Create(std::move(args));
  }

  std::unique_ptr<IsolatedDevmgr> CreateDevmgrPlatTest() {
    devmgr_launcher::Args args;
    auto device_list_ptr = std::unique_ptr<fbl::Vector<board_test::DeviceEntry>>(
        new fbl::Vector<board_test::DeviceEntry>());
    args.sys_device_driver = kPlatformDriver;

    args.stdio = fbl::unique_fd(open("/dev/null", O_RDWR));
    args.driver_search_paths.push_back("/boot/driver");
    args.driver_search_paths.push_back("/boot/driver/test");
    args.disable_block_watcher = true;
    device_list_ptr->push_back(kRtcDeviceEntry);
    device_list_ptr->push_back(kCrashDeviceEntry);
    return IsolatedDevmgr::Create(std::move(args), std::move(device_list_ptr));
  }

  fidl::InterfaceHandle<fuchsia::hardware::ethertap::TapDevice> CreateTapDevice(
      const zx::channel& devfs) {
    fidl::SynchronousInterfacePtr<fuchsia::hardware::ethertap::TapControl> tapctl;
    fdio_service_connect_at(devfs.get(), "test/tapctl",
                            tapctl.NewRequest().TakeChannel().release());
    fuchsia::hardware::ethertap::Config config;
    config.mtu = 1500;
    config.options = 0;
    config.features = 0;
    const uint8_t mac[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
    memcpy(config.mac.octets.data(), mac, sizeof(mac));

    fidl::InterfaceHandle<fuchsia::hardware::ethertap::TapDevice> device;
    zx_status_t status, o_status;
    if ((status = tapctl->OpenDevice("tap_device", std::move(config), device.NewRequest(),
                                     &o_status)) != ZX_OK ||
        o_status != ZX_OK) {
      fprintf(stderr, "status: %d, o_status: %d\n", status, o_status);
      // discard channel
      device = nullptr;
    }
    return device;
  }

  void EnableVirtualAudio(const zx::channel& devfs) {
    fuchsia::virtualaudio::ForwarderPtr virtualaudio;
    fdio_service_connect_at(devfs.get(), "test/virtual_audio",
                            virtualaudio.NewRequest().TakeChannel().release());

    // Perform a simple RPC with a reply to sanity check we're talking to the driver.
    fidl::SynchronousInterfacePtr<fuchsia::virtualaudio::Control> control_sync_ptr;
    virtualaudio->SendControl(control_sync_ptr.NewRequest());
    ASSERT_EQ(ZX_OK, control_sync_ptr->Enable());
  }
};

TEST_F(DevmgrTest, CreateTapSysdev) {
  auto devmgr = CreateDevmgrSysdev();
  ASSERT_TRUE(devmgr);
  ASSERT_EQ(devmgr->WaitForFile("test/tapctl"), ZX_OK);

  fidl::InterfaceHandle<fuchsia::io::Directory> dir;
  devmgr->Connect(dir.NewRequest().TakeChannel());
  auto tap = CreateTapDevice(dir.channel());
  ASSERT_TRUE(tap);
  // after having created tap, we should be able to see an ethernet device show
  // up:
  ASSERT_EQ(devmgr->WaitForFile("class/ethernet/000"), ZX_OK);
}

TEST_F(DevmgrTest, DeviceEntryEnumerationTest) {
  auto devmgr = CreateDevmgrPlatTest();
  ASSERT_TRUE(devmgr);

  fbl::unique_fd fd;

  ASSERT_EQ(ZX_OK, devmgr_integration_test::RecursiveWaitForFile(devmgr->devfs_root(),
                                                                 "sys/platform", &fd));
  ASSERT_EQ(ZX_OK, devmgr_integration_test::RecursiveWaitForFile(devmgr->devfs_root(),
                                                                 "sys/platform/test-board", &fd));
  ASSERT_EQ(ZX_OK, devmgr_integration_test::RecursiveWaitForFile(
                       devmgr->devfs_root(), "sys/platform/00:00:f/fallback-rtc", &fd));
}

TEST_F(DevmgrTest, ExceptionCallback) {
  auto devmgr = CreateDevmgrPlatTest();
  ASSERT_TRUE(devmgr);

  bool exception = false;
  devmgr->SetExceptionCallback([&exception]() { exception = true; });

  ASSERT_EQ(devmgr->WaitForFile("sys/platform/11:00:1f"), ZX_OK);

  zx_handle_t dir;
  ASSERT_EQ(fdio_get_service_handle(devmgr->root(), &dir), ZX_OK);

  RunLoopUntil([&exception, &dir]() {
    // keep trying to open crash-device until we see an exception
    zx::channel a, b;
    EXPECT_EQ(zx::channel::create(0, &a, &b), ZX_OK);
    fdio_service_connect_at(dir, "sys/platform/11:00:1f/crash-device", b.release());

    return exception;
  });
}

TEST_F(DevmgrTest, ExposedThroughComponent) {
  auto ctx = sys::ComponentContext::CreateAndServeOutgoingDirectory();
  fidl::InterfacePtr<fuchsia::sys::Launcher> launcher;
  ctx->svc()->Connect(launcher.NewRequest());

  zx::channel req;
  auto services = sys::ServiceDirectory::CreateWithRequest(&req);

  fuchsia::sys::LaunchInfo info;
  info.directory_request = std::move(req);
  info.url =
      "fuchsia-pkg://fuchsia.com/isolated-devmgr-tests-package#meta/"
      "ethertap-devmgr.cmx";
  fidl::InterfacePtr<fuchsia::sys::ComponentController> ctlr;

  launcher->CreateComponent(std::move(info), ctlr.NewRequest());
  ctlr.set_error_handler([](zx_status_t err) { FAIL() << "Controller shouldn't exit"; });

  zx::channel devfs_req, devfs;
  zx::channel::create(0, &devfs_req, &devfs);
  services->Connect("fuchsia.example.IsolatedDevmgr", std::move(devfs_req));

  auto tap = CreateTapDevice(devfs);
  ASSERT_TRUE(tap);
}

TEST_F(DevmgrTest, ExposeDriverFromComponentNamespace) {
  auto ctx = sys::ComponentContext::CreateAndServeOutgoingDirectory();
  fidl::InterfacePtr<fuchsia::sys::Launcher> launcher;
  ctx->svc()->Connect(launcher.NewRequest());

  zx::channel req;
  auto services = sys::ServiceDirectory::CreateWithRequest(&req);

  fuchsia::sys::LaunchInfo info;
  info.directory_request = std::move(req);
  info.url =
      "fuchsia-pkg://fuchsia.com/isolated-devmgr-tests-package#meta/"
      "virtual-audio-devmgr.cmx";
  fidl::InterfacePtr<fuchsia::sys::ComponentController> ctlr;

  launcher->CreateComponent(std::move(info), ctlr.NewRequest());
  ctlr.set_error_handler([](zx_status_t err) { FAIL() << "Controller shouldn't exit"; });

  zx::channel devfs_req, devfs;
  zx::channel::create(0, &devfs_req, &devfs);
  services->Connect("fuchsia.example.IsolatedDevmgr", std::move(devfs_req));

  EnableVirtualAudio(devfs);
}

TEST_F(DevmgrTest, ExposeDevfsToHub) {
  auto ctx = sys::ComponentContext::CreateAndServeOutgoingDirectory();
  fidl::InterfacePtr<fuchsia::sys::Launcher> launcher;
  ctx->svc()->Connect(launcher.NewRequest());

  fuchsia::sys::LaunchInfo info;
  info.url =
      "fuchsia-pkg://fuchsia.com/isolated-devmgr-tests-package#meta/virtual-audio-devmgr.cmx";
  auto echo_svc = sys::ServiceDirectory::CreateWithRequest(&info.directory_request);
  fidl::InterfacePtr<fuchsia::sys::ComponentController> ctlr;
  launcher->CreateComponent(std::move(info), ctlr.NewRequest());

  ctlr.set_error_handler([](zx_status_t err) { FAIL() << "Controller shouldn't exit"; });
  bool ready = false;
  ctlr.events().OnDirectoryReady = [&ready] { ready = true; };
  RunLoopUntil([&ready] { return ready; });
  ASSERT_TRUE(ready);

  // Verify that devfs is indeed visible in outgoing directory
  constexpr char kGlob[] = "/hub/c/virtual-audio-devmgr.cmx/*/out/dev";
  files::Glob glob(kGlob);
  EXPECT_EQ(glob.size(), 1u) << kGlob << " expected to match exactly once.";
}

TEST_F(DevmgrTest, DiagnosticsFiles) {
  auto devmgr = CreateDevmgrSysdev();
  ASSERT_TRUE(devmgr);

  fbl::unique_fd fd;
  ASSERT_EQ(ZX_OK, devmgr_integration_test::RecursiveWaitForFileReadOnly(devmgr->devfs_root(),
                                                                         "diagnostics", &fd));
  ASSERT_EQ(ZX_OK, devmgr_integration_test::RecursiveWaitForFileReadOnly(devmgr->devfs_root(),
                                                                         "diagnostics/class", &fd));
  ASSERT_EQ(ZX_OK, devmgr_integration_test::RecursiveWaitForFileReadOnly(
                       devmgr->devfs_root(), "diagnostics/driver_manager", &fd));
  ASSERT_EQ(ZX_OK, devmgr_integration_test::RecursiveWaitForFileReadOnly(
                       devmgr->devfs_root(), "diagnostics/driver_manager/dm.inspect", &fd));
  ASSERT_EQ(ZX_OK, devmgr_integration_test::RecursiveWaitForFileReadOnly(
                       devmgr->devfs_root(), "diagnostics/driver_manager/driver_host", &fd));

  // TODO(fxbug.dev/50569): Add test for root,sys,misc,test driver_host files once koids are
  // available via dm.inspect
}

}  // namespace testing
}  // namespace isolated_devmgr
