// 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 "lib/usb-virtual-bus-launcher/usb-virtual-bus-launcher.h"

#include <fcntl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/ddk/platform-defs.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <lib/fdio/namespace.h>
#include <lib/fdio/spawn.h>
#include <lib/fdio/unsafe.h>
#include <lib/fdio/watcher.h>
#include <lib/fidl-async/cpp/bind.h>
#include <lib/usb-peripheral-utils/event-watcher.h>
#include <sys/stat.h>
#include <unistd.h>
#include <zircon/hw/usb.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>

#include <zxtest/zxtest.h>

namespace usb_virtual_bus_base {

using driver_integration_test::IsolatedDevmgr;
using usb_virtual_bus::ValidateResult;

USBVirtualBusBase::USBVirtualBusBase() {
  args_.disable_block_watcher = true;

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

  ASSERT_OK(IsolatedDevmgr::Create(&args_, &devmgr_));

  fbl::unique_fd fd;
  device_watcher::RecursiveWaitForFile(devmgr_.devfs_root(), "sys/platform/11:03:0/usb-virtual-bus",
                                       &fd);
  ASSERT_TRUE(fd.is_valid());

  zx::channel virtual_bus;
  ASSERT_OK(fdio_get_service_handle(fd.release(), virtual_bus.reset_and_get_address()));
  virtual_bus_ =
      fidl::BindSyncClient<fuchsia_hardware_usb_virtual_bus::Bus>(std::move(virtual_bus));

  auto enable_result = virtual_bus_->Enable();
  ASSERT_NO_FATAL_FAILURE(ValidateResult(enable_result));

  fd.reset(openat(devmgr_.devfs_root().get(), "class/usb-peripheral", O_RDONLY));
  fbl::String devpath;
  while (fdio_watch_directory(fd.get(), usb_virtual_bus::WaitForAnyFile, ZX_TIME_INFINITE,
                              &devpath) != ZX_ERR_STOP)
    continue;

  devpath = fbl::String::Concat({fbl::String("class/usb-peripheral/"), fbl::String(devpath)});
  fd.reset(openat(devmgr_.devfs_root().get(), devpath.c_str(), O_RDWR));

  zx::channel peripheral;
  ASSERT_OK(fdio_get_service_handle(fd.release(), peripheral.reset_and_get_address()));
  peripheral_ =
      fidl::BindSyncClient<fuchsia_hardware_usb_peripheral::Device>(std::move(peripheral));

  ASSERT_NO_FATAL_FAILURE(ClearPeripheralDeviceFunctions());
}

int USBVirtualBusBase::GetRootFd() { return devmgr_.devfs_root().get(); }

void USBVirtualBusBase::SetupPeripheralDevice(DeviceDescriptor&& device_desc,
                                              std::vector<ConfigurationDescriptor> config_descs) {
  zx::channel handles[2];
  ASSERT_OK(zx::channel::create(0, handles, handles + 1));
  auto set_result = peripheral_->SetStateChangeListener(std::move(handles[1]));
  ASSERT_OK(set_result.status());

  auto set_config = peripheral_->SetConfiguration(
      std::move(device_desc),
      fidl::VectorView<ConfigurationDescriptor>::FromExternal(config_descs));
  ASSERT_OK(set_config.status());
  ASSERT_FALSE(set_config->is_error());

  async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
  usb_peripheral_utils::EventWatcher watcher(&loop, std::move(handles[0]), 1);
  loop.Run();
  ASSERT_TRUE(watcher.all_functions_registered());

  auto connect_result = virtual_bus_->Connect();
  ASSERT_NO_FATAL_FAILURE(ValidateResult(connect_result));
}

void USBVirtualBusBase::ClearPeripheralDeviceFunctions() {
  zx::channel handles[2];
  ASSERT_OK(zx::channel::create(0, handles, handles + 1));
  auto set_result = peripheral_->SetStateChangeListener(std::move(handles[1]));
  ASSERT_OK(set_result.status());

  auto clear_functions = peripheral_->ClearFunctions();
  ASSERT_OK(clear_functions.status());

  async::Loop loop(&kAsyncLoopConfigNeverAttachToThread);
  usb_peripheral_utils::EventWatcher watcher(&loop, std::move(handles[0]), 1);
  loop.Run();
  ASSERT_TRUE(watcher.all_functions_cleared());
}

}  // namespace usb_virtual_bus_base
