// 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;
    args.disable_netsvc = 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;
    args.disable_netsvc = 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
