// Copyright 2018 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 <drm_fourcc.h>
#include <fuchsia/scenic/allocation/cpp/fidl_test_base.h>
#include <fuchsia/sysmem/cpp/fidl_test_base.h>
#include <fuchsia/virtualization/cpp/fidl.h>
#include <fuchsia/virtualization/hardware/cpp/fidl.h>
#include <lib/zx/socket.h>
#include <string.h>

#include <iterator>

#include <fbl/algorithm.h>
#include <virtio/wl.h>

#include "src/virtualization/bin/vmm/device/test_with_device.h"
#include "src/virtualization/bin/vmm/device/virtio_queue_fake.h"

namespace {

#define VIRTWL_VQ_IN 0
#define VIRTWL_VQ_OUT 1
#define VIRTWL_NEXT_VFD_ID_BASE 0x40000000

static constexpr char kVirtioWlUrl[] = "fuchsia-pkg://fuchsia.com/virtio_wl#meta/virtio_wl.cmx";
static constexpr uint16_t kNumQueues = 2;
static constexpr uint16_t kQueueSize = 32;
static constexpr uint32_t kVirtioWlVmarSize = 1 << 16;
static constexpr uint32_t kAllocateFlags = ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE;
static constexpr uint32_t kImportVmoSize = 4096;
static constexpr uint32_t kDmabufWidth = 64;
static constexpr uint32_t kDmabufHeight = 64;
static constexpr uint32_t kDmabufDrmFormat = DRM_FORMAT_ARGB8888;
static constexpr fuchsia::sysmem::PixelFormatType kDmabufSysmemFormat =
    fuchsia::sysmem::PixelFormatType::BGRA32;

class TestWaylandDispatcher : public fuchsia::virtualization::WaylandDispatcher {
 public:
  TestWaylandDispatcher(fit::function<void(zx::channel)> callback)
      : callback_(std::move(callback)) {}

  fidl::InterfaceHandle<fuchsia::virtualization::WaylandDispatcher> Bind() {
    return binding_.NewBinding();
  }

 private:
  void OnNewConnection(zx::channel channel) { callback_(std::move(channel)); }

  fit::function<void(zx::channel)> callback_;
  fidl::Binding<fuchsia::virtualization::WaylandDispatcher> binding_{this};
};

class TestBufferCollectionToken : public fuchsia::sysmem::testing::BufferCollectionToken_TestBase {
 public:
  TestBufferCollectionToken(fidl::InterfaceRequest<fuchsia::sysmem::BufferCollectionToken> request)
      : binding_{this, std::move(request)} {}

 private:
  // |fuchsia::sysmem::BufferCollection|
  void Duplicate(uint32_t rights_attenuation_mask,
                 fidl::InterfaceRequest<fuchsia::sysmem::BufferCollectionToken> request) override {
    duplicates_.emplace_back(std::make_unique<TestBufferCollectionToken>(std::move(request)));
  }
  void Sync(SyncCallback callback) override { callback(); }

  void NotImplemented_(const std::string& name) override {
    FAIL() << "Not Implemented BufferCollection." << name;
  }

  std::vector<std::unique_ptr<TestBufferCollectionToken>> duplicates_;
  fidl::Binding<fuchsia::sysmem::BufferCollectionToken> binding_;
};

class TestBufferCollection : public fuchsia::sysmem::testing::BufferCollection_TestBase {
 public:
  TestBufferCollection(fidl::InterfaceRequest<fuchsia::sysmem::BufferCollection> request)
      : binding_{this, std::move(request)} {}

 private:
  // |fuchsia::sysmem::BufferCollection|
  void Close() override { binding_.Close(ZX_OK); }
  void SetName(uint32_t priority, std::string name) override {}
  void SetConstraints(bool has_constraints,
                      fuchsia::sysmem::BufferCollectionConstraints constraints) override {}
  void WaitForBuffersAllocated(WaitForBuffersAllocatedCallback callback) override {
    fuchsia::sysmem::BufferCollectionInfo_2 info{};
    info.buffer_count = 1;
    info.settings.has_image_format_constraints = true;
    info.settings.image_format_constraints.pixel_format.type = kDmabufSysmemFormat;
    info.settings.image_format_constraints.pixel_format.has_format_modifier = true;
    info.settings.image_format_constraints.pixel_format.format_modifier.value =
        fuchsia::sysmem::FORMAT_MODIFIER_LINEAR;
    info.settings.image_format_constraints.min_coded_width = kDmabufWidth;
    info.settings.image_format_constraints.min_coded_height = kDmabufHeight;
    info.settings.image_format_constraints.max_coded_width = kDmabufWidth;
    info.settings.image_format_constraints.max_coded_height = kDmabufHeight;
    info.settings.image_format_constraints.min_bytes_per_row = kDmabufWidth * 4;
    info.settings.image_format_constraints.bytes_per_row_divisor = 1;
    zx::vmo::create(kDmabufWidth * kDmabufHeight * 4, 0, &info.buffers[0].vmo);
    callback(ZX_OK, std::move(info));
  }

  void NotImplemented_(const std::string& name) override {
    FAIL() << "Not Implemented BufferCollection." << name;
  }

  fidl::Binding<fuchsia::sysmem::BufferCollection> binding_;
};

class TestSysmemAllocator : public fuchsia::sysmem::testing::Allocator_TestBase {
 public:
  fidl::InterfaceHandle<fuchsia::sysmem::Allocator> Bind(async_dispatcher_t* dispatcher) {
    return binding_.NewBinding(dispatcher);
  }

 private:
  // |fuchsia::sysmem::Allocator|
  void AllocateSharedCollection(
      fidl::InterfaceRequest<fuchsia::sysmem::BufferCollectionToken> request) override {
    tokens_.emplace_back(std::make_unique<TestBufferCollectionToken>(std::move(request)));
  }
  void BindSharedCollection(
      fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> token,
      fidl::InterfaceRequest<fuchsia::sysmem::BufferCollection> request) override {
    collections_.emplace_back(std::make_unique<TestBufferCollection>(std::move(request)));
  }

  void NotImplemented_(const std::string& name) override {
    FAIL() << "Not Implemented Allocator." << name;
  }

  std::vector<std::unique_ptr<TestBufferCollectionToken>> tokens_;
  std::vector<std::unique_ptr<TestBufferCollection>> collections_;
  fidl::Binding<fuchsia::sysmem::Allocator> binding_{this};
};

class TestAllocator : public fuchsia::scenic::allocation::testing::Allocator_TestBase {
 public:
  fidl::InterfaceHandle<fuchsia::scenic::allocation::Allocator> Bind(
      async_dispatcher_t* dispatcher) {
    return binding_.NewBinding(dispatcher);
  }

 private:
  void RegisterBufferCollection(
      fuchsia::scenic::allocation::BufferCollectionExportToken export_token,
      fidl::InterfaceHandle<fuchsia::sysmem::BufferCollectionToken> scenic_token,
      RegisterBufferCollectionCallback callback) override {
    callback(fit::ok());
  }

  void NotImplemented_(const std::string& name) override {
    FAIL() << "Not Implemented Allocator." << name;
  }

  fidl::Binding<fuchsia::scenic::allocation::Allocator> binding_{this};
};

class VirtioWlTest : public TestWithDevice {
 public:
  VirtioWlTest()
      : wl_dispatcher_([this](zx::channel channel) { channels_.emplace_back(std::move(channel)); }),
        in_queue_(phys_mem_, PAGE_SIZE * kNumQueues, kQueueSize),
        out_queue_(phys_mem_, in_queue_.end(), kQueueSize),
        sysmem_loop_(&kAsyncLoopConfigNoAttachToCurrentThread),
        scenic_loop_(&kAsyncLoopConfigNoAttachToCurrentThread) {}

  void SetUp() override {
    uintptr_t vmar_addr;
    zx::vmar vmar;
    ASSERT_EQ(
        zx::vmar::root_self()->allocate(kAllocateFlags, 0u, kVirtioWlVmarSize, &vmar, &vmar_addr),
        ZX_OK);
    fuchsia::virtualization::hardware::StartInfo start_info;
    zx_status_t status = LaunchDevice(kVirtioWlUrl, out_queue_.end(), &start_info);
    ASSERT_EQ(ZX_OK, status);

    // Start device execution.
    services_->Connect(wl_.NewRequest());
    RunLoopUntilIdle();

    ASSERT_EQ(sysmem_loop_.StartThread(), ZX_OK);
    ASSERT_EQ(scenic_loop_.StartThread(), ZX_OK);

    wl_->Start(std::move(start_info), std::move(vmar), wl_dispatcher_.Bind(),
               sysmem_allocator_.Bind(sysmem_loop_.dispatcher()),
               scenic_allocator_.Bind(scenic_loop_.dispatcher()));
    ASSERT_EQ(ZX_OK, status);

    // Configure device queues.
    VirtioQueueFake* queues[kNumQueues] = {&in_queue_, &out_queue_};
    for (size_t i = 0; i < kNumQueues; i++) {
      auto q = queues[i];
      q->Configure(PAGE_SIZE * i, PAGE_SIZE);
      status = wl_->ConfigureQueue(i, q->size(), q->desc(), q->avail(), q->used());
      ASSERT_EQ(ZX_OK, status);
    }
  }

  zx_status_t CreateNew(uint32_t vfd_id, uint8_t byte) {
    virtio_wl_ctrl_vfd_new_t request = {};
    request.hdr.type = VIRTIO_WL_CMD_VFD_NEW;
    request.vfd_id = vfd_id;
    request.size = PAGE_SIZE;
    virtio_wl_ctrl_vfd_new_t* response;
    uint16_t descriptor_id;
    zx_status_t status = DescriptorChainBuilder(out_queue_)
                             .AppendReadableDescriptor(&request, sizeof(request))
                             .AppendWritableDescriptor(&response, sizeof(*response))
                             .Build(&descriptor_id);
    if (status != ZX_OK) {
      return status;
    }
    status = wl_->NotifyQueue(VIRTWL_VQ_OUT);
    if (status != ZX_OK) {
      return status;
    }
    status = WaitOnInterrupt();
    if (status != ZX_OK) {
      return status;
    }

    auto used_elem = NextUsed(&out_queue_);
    if (!used_elem || used_elem->id != descriptor_id || used_elem->len != sizeof(*response) ||
        response->hdr.type != VIRTIO_WL_RESP_VFD_NEW || !response->pfn ||
        response->size != PAGE_SIZE) {
      return ZX_ERR_INTERNAL;
    }

    memset(reinterpret_cast<void*>(response->pfn * PAGE_SIZE), byte, PAGE_SIZE);
    return ZX_OK;
  }

  zx_status_t CreateConnection(uint32_t vfd_id) {
    virtio_wl_ctrl_vfd_new_t request = {};
    request.hdr.type = VIRTIO_WL_CMD_VFD_NEW_CTX;
    request.vfd_id = vfd_id;
    virtio_wl_ctrl_vfd_new_t* response;
    uint16_t descriptor_id;
    zx_status_t status = DescriptorChainBuilder(out_queue_)
                             .AppendReadableDescriptor(&request, sizeof(request))
                             .AppendWritableDescriptor(&response, sizeof(*response))
                             .Build(&descriptor_id);
    if (status != ZX_OK) {
      return status;
    }
    status = wl_->NotifyQueue(VIRTWL_VQ_OUT);
    if (status != ZX_OK) {
      return status;
    }
    status = WaitOnInterrupt();
    if (status != ZX_OK) {
      return status;
    }

    auto used_elem = NextUsed(&out_queue_);
    return (used_elem && used_elem->id == descriptor_id && used_elem->len == sizeof(*response) &&
            response->hdr.type == VIRTIO_WL_RESP_VFD_NEW)
               ? ZX_OK
               : ZX_ERR_INTERNAL;
  }

  zx_status_t CreatePipe(uint32_t vfd_id) {
    virtio_wl_ctrl_vfd_new_t request = {};
    request.hdr.type = VIRTIO_WL_CMD_VFD_NEW_PIPE;
    request.vfd_id = vfd_id;
    request.flags = VIRTIO_WL_VFD_READ;
    virtio_wl_ctrl_vfd_new_t* response;
    uint16_t descriptor_id;
    zx_status_t status = DescriptorChainBuilder(out_queue_)
                             .AppendReadableDescriptor(&request, sizeof(request))
                             .AppendWritableDescriptor(&response, sizeof(*response))
                             .Build(&descriptor_id);
    if (status != ZX_OK) {
      return status;
    }
    status = wl_->NotifyQueue(VIRTWL_VQ_OUT);
    if (status != ZX_OK) {
      return status;
    }
    status = WaitOnInterrupt();
    if (status != ZX_OK) {
      return status;
    }

    auto used_elem = NextUsed(&out_queue_);
    return (used_elem && used_elem->id == descriptor_id && used_elem->len == sizeof(*response) &&
            response->hdr.type == VIRTIO_WL_RESP_VFD_NEW)
               ? ZX_OK
               : ZX_ERR_INTERNAL;
  }

  std::optional<VirtioQueueFake::UsedElement> NextUsed(VirtioQueueFake* queue) {
    auto elem = queue->NextUsed();
    while (!elem && WaitOnInterrupt() == ZX_OK) {
      elem = queue->NextUsed();
    }
    return elem;
  }

 protected:
  TestWaylandDispatcher wl_dispatcher_;
  TestSysmemAllocator sysmem_allocator_;
  TestAllocator scenic_allocator_;
  fuchsia::virtualization::hardware::VirtioWaylandSyncPtr wl_;
  VirtioQueueFake in_queue_;
  VirtioQueueFake out_queue_;
  std::vector<zx::channel> channels_;
  async::Loop sysmem_loop_;
  async::Loop scenic_loop_;
};

TEST_F(VirtioWlTest, HandleNew) {
  virtio_wl_ctrl_vfd_new_t request = {};
  request.hdr.type = VIRTIO_WL_CMD_VFD_NEW;
  request.vfd_id = 1u;
  request.size = 4000u;
  virtio_wl_ctrl_vfd_new_t* response;
  uint16_t descriptor_id;
  ASSERT_EQ(DescriptorChainBuilder(out_queue_)
                .AppendReadableDescriptor(&request, sizeof(request))
                .AppendWritableDescriptor(&response, sizeof(*response))
                .Build(&descriptor_id),
            ZX_OK);

  ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);

  auto used_elem = NextUsed(&out_queue_);
  EXPECT_TRUE(used_elem);
  EXPECT_EQ(used_elem->id, descriptor_id);
  EXPECT_EQ(used_elem->len, sizeof(*response));
  EXPECT_EQ(response->hdr.type, VIRTIO_WL_RESP_VFD_NEW);
  EXPECT_EQ(response->hdr.flags, 0u);
  EXPECT_EQ(response->vfd_id, 1u);
  EXPECT_EQ(response->flags, static_cast<uint32_t>(VIRTIO_WL_VFD_READ | VIRTIO_WL_VFD_WRITE));
  EXPECT_GT(response->pfn, 0u);
  EXPECT_EQ(response->size, static_cast<uint32_t>(PAGE_SIZE));
  memset(reinterpret_cast<void*>(response->pfn * PAGE_SIZE), 0xff, 4000u);
}

TEST_F(VirtioWlTest, HandleClose) {
  ASSERT_EQ(CreateNew(1u, 0xff), ZX_OK);

  virtio_wl_ctrl_vfd_t request = {};
  request.hdr.type = VIRTIO_WL_CMD_VFD_CLOSE;
  request.vfd_id = 1u;
  virtio_wl_ctrl_hdr_t* response;
  uint16_t descriptor_id;
  ASSERT_EQ(DescriptorChainBuilder(out_queue_)
                .AppendReadableDescriptor(&request, sizeof(request))
                .AppendWritableDescriptor(&response, sizeof(*response))
                .Build(&descriptor_id),
            ZX_OK);

  ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);
  auto used_elem = NextUsed(&out_queue_);
  EXPECT_TRUE(used_elem);
  EXPECT_EQ(used_elem->id, descriptor_id);
  EXPECT_EQ(used_elem->len, sizeof(*response));
  EXPECT_EQ(response->type, VIRTIO_WL_RESP_OK);
}

TEST_F(VirtioWlTest, HandleNewCtx) {
  virtio_wl_ctrl_vfd_new_t request = {};
  request.hdr.type = VIRTIO_WL_CMD_VFD_NEW_CTX;
  request.vfd_id = 1u;
  virtio_wl_ctrl_vfd_new_t* response;
  uint16_t descriptor_id;
  ASSERT_EQ(DescriptorChainBuilder(out_queue_)
                .AppendReadableDescriptor(&request, sizeof(request))
                .AppendWritableDescriptor(&response, sizeof(*response))
                .Build(&descriptor_id),
            ZX_OK);

  ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);
  auto used_elem = NextUsed(&out_queue_);
  EXPECT_TRUE(used_elem);
  EXPECT_EQ(used_elem->id, descriptor_id);
  EXPECT_EQ(used_elem->len, sizeof(*response));
  EXPECT_EQ(response->hdr.type, VIRTIO_WL_RESP_VFD_NEW);
  EXPECT_EQ(response->hdr.flags, 0u);
  EXPECT_EQ(response->vfd_id, 1u);
  EXPECT_EQ(response->flags, static_cast<uint32_t>(VIRTIO_WL_VFD_READ | VIRTIO_WL_VFD_WRITE));

  RunLoopUntilIdle();
  EXPECT_EQ(channels_.size(), 1u);
  channels_.clear();
}

TEST_F(VirtioWlTest, HandleNewPipe) {
  virtio_wl_ctrl_vfd_new_t request = {};
  request.hdr.type = VIRTIO_WL_CMD_VFD_NEW_PIPE;
  request.vfd_id = 1u;
  request.flags = VIRTIO_WL_VFD_READ;
  virtio_wl_ctrl_vfd_new_t* response;
  uint16_t descriptor_id;
  ASSERT_EQ(DescriptorChainBuilder(out_queue_)
                .AppendReadableDescriptor(&request, sizeof(request))
                .AppendWritableDescriptor(&response, sizeof(*response))
                .Build(&descriptor_id),
            ZX_OK);

  ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);
  auto used_elem = NextUsed(&out_queue_);
  EXPECT_TRUE(used_elem);
  EXPECT_EQ(used_elem->id, descriptor_id);
  EXPECT_EQ(used_elem->len, sizeof(*response));
  EXPECT_EQ(response->hdr.type, VIRTIO_WL_RESP_VFD_NEW);
  EXPECT_EQ(response->hdr.flags, 0u);
  EXPECT_EQ(response->vfd_id, 1u);
  EXPECT_EQ(response->flags, static_cast<uint32_t>(VIRTIO_WL_VFD_READ));
}

TEST_F(VirtioWlTest, HandleDmabuf) {
  virtio_wl_ctrl_vfd_new_t request = {};
  request.hdr.type = VIRTIO_WL_CMD_VFD_NEW_DMABUF;
  request.vfd_id = 1u;
  request.dmabuf.format = kDmabufDrmFormat;
  request.dmabuf.width = kDmabufWidth;
  request.dmabuf.height = kDmabufHeight;
  virtio_wl_ctrl_vfd_new_t* response;
  uint16_t descriptor_id;
  ASSERT_EQ(DescriptorChainBuilder(out_queue_)
                .AppendReadableDescriptor(&request, sizeof(request))
                .AppendWritableDescriptor(&response, sizeof(*response))
                .Build(&descriptor_id),
            ZX_OK);

  ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);
  auto used_elem = NextUsed(&out_queue_);
  EXPECT_TRUE(used_elem);
  EXPECT_EQ(used_elem->id, descriptor_id);
  EXPECT_EQ(used_elem->len, sizeof(*response));
  EXPECT_EQ(response->hdr.type, VIRTIO_WL_RESP_VFD_NEW_DMABUF);
  EXPECT_EQ(response->hdr.flags, 0u);
  EXPECT_EQ(response->vfd_id, 1u);
  EXPECT_EQ(response->flags, static_cast<uint32_t>(VIRTIO_WL_VFD_READ | VIRTIO_WL_VFD_WRITE));
  EXPECT_GT(response->pfn, 0u);
  EXPECT_GT(response->size, 0u);
}

TEST_F(VirtioWlTest, HandleSend) {
  ASSERT_EQ(CreateNew(1u, 0xaa), ZX_OK);
  ASSERT_EQ(CreatePipe(2u), ZX_OK);
  ASSERT_EQ(CreateConnection(3u), ZX_OK);

  RunLoopUntilIdle();
  ASSERT_EQ(channels_.size(), 1u);

  uint8_t request[sizeof(virtio_wl_ctrl_vfd_send_t) + sizeof(uint32_t) * 3];
  virtio_wl_ctrl_vfd_send_t* header = reinterpret_cast<virtio_wl_ctrl_vfd_send_t*>(request);
  header->hdr.type = VIRTIO_WL_CMD_VFD_SEND;
  header->vfd_id = 3u;
  header->vfd_count = 2u;
  uint32_t* vfds = reinterpret_cast<uint32_t*>(header + 1);
  vfds[0] = 1u;
  vfds[1] = 2u;
  vfds[2] = 1234u;  // payload
  virtio_wl_ctrl_hdr_t* response;
  uint16_t descriptor_id;
  ASSERT_EQ(DescriptorChainBuilder(out_queue_)
                .AppendReadableDescriptor(&request, sizeof(request))
                .AppendWritableDescriptor(&response, sizeof(*response))
                .Build(&descriptor_id),
            ZX_OK);

  ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);
  auto used_elem = NextUsed(&out_queue_);
  EXPECT_TRUE(used_elem);
  EXPECT_EQ(used_elem->id, descriptor_id);
  EXPECT_EQ(used_elem->len, sizeof(*response));
  EXPECT_EQ(response->type, VIRTIO_WL_RESP_OK);

  uint32_t data;
  zx_handle_t handles[ZX_CHANNEL_MAX_MSG_HANDLES];
  uint32_t actual_bytes, actual_handles;
  ASSERT_EQ(zx_channel_read(channels_[0].get(), 0, &data, handles, sizeof(data), std::size(handles),
                            &actual_bytes, &actual_handles),
            ZX_OK);
  EXPECT_EQ(actual_handles, 2u);
  EXPECT_EQ(actual_bytes, sizeof(data));
  EXPECT_EQ(data, 1234u);

  zx::vmo vmo(handles[0]);
  zx::socket socket(handles[1]);

  // Verify data transfer using shared memory.
  uintptr_t addr;
  ASSERT_EQ(
      zx::vmar::root_self()->map(ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0, vmo, 0, PAGE_SIZE, &addr),
      ZX_OK);
  EXPECT_EQ(*reinterpret_cast<uint8_t*>(addr), 0xaa);
  ASSERT_EQ(zx::vmar::root_self()->unmap(addr, PAGE_SIZE), ZX_OK);

  // Verify data transfer over pipe.
  size_t actual_size;
  ASSERT_EQ(socket.write(0, &data, sizeof(data), &actual_size), ZX_OK);
  EXPECT_EQ(actual_size, sizeof(data));
  RunLoopUntilIdle();

  size_t buffer_size = sizeof(virtio_wl_ctrl_vfd_recv_t) + sizeof(data);
  uint8_t* buffer;
  ASSERT_EQ(DescriptorChainBuilder(in_queue_)
                .AppendWritableDescriptor(&buffer, buffer_size)
                .Build(&descriptor_id),
            ZX_OK);
  virtio_wl_ctrl_vfd_recv_t* recv_header = reinterpret_cast<virtio_wl_ctrl_vfd_recv_t*>(buffer);

  ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_IN), ZX_OK);
  used_elem = NextUsed(&in_queue_);
  EXPECT_TRUE(used_elem);
  EXPECT_EQ(used_elem->id, descriptor_id);
  EXPECT_EQ(used_elem->len, buffer_size);
  EXPECT_EQ(recv_header->hdr.type, VIRTIO_WL_CMD_VFD_RECV);
  EXPECT_EQ(recv_header->hdr.flags, 0u);
  EXPECT_EQ(recv_header->vfd_id, 2u);
  EXPECT_EQ(recv_header->vfd_count, 0u);
  EXPECT_EQ(*reinterpret_cast<uint32_t*>(recv_header + 1), 1234u);

  channels_.clear();
}

TEST_F(VirtioWlTest, Recv) {
  ASSERT_EQ(CreateConnection(1u), ZX_OK);
  RunLoopUntilIdle();
  ASSERT_EQ(channels_.size(), 1u);

  zx::vmo vmo;
  ASSERT_EQ(zx::vmo::create(PAGE_SIZE, 0, &vmo), ZX_OK);
  uintptr_t addr;
  ASSERT_EQ(
      zx::vmar::root_self()->map(ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0, vmo, 0, PAGE_SIZE, &addr),
      ZX_OK);
  memset(reinterpret_cast<void*>(addr), 0xaa, PAGE_SIZE);
  ASSERT_EQ(zx::vmar::root_self()->unmap(addr, PAGE_SIZE), ZX_OK);

  zx::socket socket, remote_socket;
  ASSERT_EQ(zx::socket::create(0, &socket, &remote_socket), ZX_OK);

  uint32_t data = 1234u;
  zx_handle_t handles[] = {vmo.release(), remote_socket.release()};
  ASSERT_EQ(
      zx_channel_write(channels_[0].get(), 0, &data, sizeof(data), handles, std::size(handles)),
      ZX_OK);
  RunLoopUntilIdle();

  virtio_wl_ctrl_vfd_new_t* new_vfd_cmd[2];
  size_t buffer_size =
      sizeof(virtio_wl_ctrl_vfd_recv_t) + sizeof(uint32_t) * std::size(handles) + sizeof(data);
  uint8_t* buffer;
  uint16_t descriptor_id[3];
  ASSERT_EQ(DescriptorChainBuilder(in_queue_)
                .AppendWritableDescriptor(&buffer, buffer_size)
                .Build(&descriptor_id[0]),
            ZX_OK);
  ASSERT_EQ(DescriptorChainBuilder(in_queue_)
                .AppendWritableDescriptor(&new_vfd_cmd[0], sizeof(virtio_wl_ctrl_vfd_new_t))
                .Build(&descriptor_id[1]),
            ZX_OK);
  ASSERT_EQ(DescriptorChainBuilder(in_queue_)
                .AppendWritableDescriptor(&new_vfd_cmd[1], sizeof(virtio_wl_ctrl_vfd_new_t))
                .Build(&descriptor_id[2]),
            ZX_OK);
  virtio_wl_ctrl_vfd_recv_t* header = reinterpret_cast<virtio_wl_ctrl_vfd_recv_t*>(buffer);
  uint32_t* vfds = reinterpret_cast<uint32_t*>(header + 1);
  ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_IN), ZX_OK);

  // Descriptors should be returned in the order:
  //   descriptor_id[1] -> NEW_VFD (VMO)
  //   descriptor_id[2] -> NEW_VFD (SOCKET)
  //   descriptor_id[0] -> RECV
  // This is because the RECV message is read out of the channel directly into
  // descriptor_id[0], but then we see the new VFDs that need to be created
  // first.

  // descriptor_id[1] -> NEW_VFD (VMO)
  auto used_elem = NextUsed(&in_queue_);
  EXPECT_TRUE(used_elem);
  EXPECT_EQ(used_elem->id, descriptor_id[1]);
  EXPECT_EQ(used_elem->len, sizeof(virtio_wl_ctrl_vfd_new_t));

  // descriptor_id[2] -> NEW_VFD (SOCKET)
  used_elem = NextUsed(&in_queue_);
  EXPECT_TRUE(used_elem);
  EXPECT_EQ(used_elem->id, descriptor_id[2]);
  EXPECT_EQ(used_elem->len, sizeof(virtio_wl_ctrl_vfd_new_t));

  // descriptor_id[0] -> RECV
  used_elem = NextUsed(&in_queue_);
  EXPECT_TRUE(used_elem);
  EXPECT_EQ(used_elem->id, descriptor_id[0]);
  EXPECT_EQ(used_elem->len, buffer_size);

  EXPECT_EQ(new_vfd_cmd[0]->hdr.type, VIRTIO_WL_CMD_VFD_NEW);
  EXPECT_EQ(new_vfd_cmd[0]->hdr.flags, 0u);
  EXPECT_EQ(new_vfd_cmd[0]->vfd_id, static_cast<uint32_t>(VIRTWL_NEXT_VFD_ID_BASE));
  EXPECT_EQ(new_vfd_cmd[0]->flags, static_cast<uint32_t>(VIRTIO_WL_VFD_READ | VIRTIO_WL_VFD_WRITE));
  // We use memcpy to avoid an unaligned access, due to the packed structure.
  uint64_t pfn;
  memcpy(&pfn, &new_vfd_cmd[0]->pfn, sizeof(pfn));
  EXPECT_GT(pfn, 0u);
  EXPECT_EQ(new_vfd_cmd[0]->size, static_cast<uint32_t>(PAGE_SIZE));
  EXPECT_EQ(*reinterpret_cast<uint8_t*>(new_vfd_cmd[0]->pfn * PAGE_SIZE), 0xaa);

  EXPECT_EQ(new_vfd_cmd[1]->hdr.type, VIRTIO_WL_CMD_VFD_NEW_PIPE);
  EXPECT_EQ(new_vfd_cmd[1]->hdr.flags, 0u);
  EXPECT_EQ(new_vfd_cmd[1]->vfd_id, static_cast<uint32_t>(VIRTWL_NEXT_VFD_ID_BASE + 1));
  EXPECT_EQ(new_vfd_cmd[1]->flags, static_cast<uint32_t>(VIRTIO_WL_VFD_READ | VIRTIO_WL_VFD_WRITE));

  EXPECT_EQ(header->hdr.type, VIRTIO_WL_CMD_VFD_RECV);
  EXPECT_EQ(header->hdr.flags, 0u);
  EXPECT_EQ(header->vfd_id, 1u);
  EXPECT_EQ(header->vfd_count, 2u);
  EXPECT_EQ(vfds[0], static_cast<uint32_t>(VIRTWL_NEXT_VFD_ID_BASE));
  EXPECT_EQ(vfds[1], static_cast<uint32_t>(VIRTWL_NEXT_VFD_ID_BASE + 1));
  EXPECT_EQ(*reinterpret_cast<uint32_t*>(vfds + std::size(handles)), 1234u);

  {  // Check that closing shared memory works as expected.
    uint16_t descriptor_id;
    virtio_wl_ctrl_vfd_t request = {};
    request.hdr.type = VIRTIO_WL_CMD_VFD_CLOSE;
    request.vfd_id = VIRTWL_NEXT_VFD_ID_BASE;
    virtio_wl_ctrl_hdr_t* response;
    ASSERT_EQ(DescriptorChainBuilder(out_queue_)
                  .AppendReadableDescriptor(&request, sizeof(request))
                  .AppendWritableDescriptor(&response, sizeof(*response))
                  .Build(&descriptor_id),
              ZX_OK);

    ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);
    used_elem = NextUsed(&out_queue_);
    EXPECT_TRUE(used_elem);
    EXPECT_EQ(used_elem->id, descriptor_id);
    EXPECT_EQ(used_elem->len, sizeof(*response));
    EXPECT_EQ(response->type, VIRTIO_WL_RESP_OK);
  }

  {  // Check that writing to pipe works as expected.
    uint16_t descriptor_id = 0;
    uint8_t send_request[sizeof(virtio_wl_ctrl_vfd_send_t) + sizeof(uint32_t)];
    virtio_wl_ctrl_vfd_send_t* send_header =
        reinterpret_cast<virtio_wl_ctrl_vfd_send_t*>(send_request);
    send_header->hdr.type = VIRTIO_WL_CMD_VFD_SEND;
    send_header->vfd_id = VIRTWL_NEXT_VFD_ID_BASE + 1;
    send_header->vfd_count = 0;
    *reinterpret_cast<uint32_t*>(send_header + 1) = 1234u;  // payload
    virtio_wl_ctrl_hdr_t* send_response;
    ASSERT_EQ(DescriptorChainBuilder(out_queue_)
                  .AppendReadableDescriptor(&send_request, sizeof(send_request))
                  .AppendWritableDescriptor(&send_response, sizeof(*send_response))
                  .Build(&descriptor_id),
              ZX_OK);

    ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);
    used_elem = NextUsed(&out_queue_);
    EXPECT_TRUE(used_elem);
    EXPECT_EQ(used_elem->id, descriptor_id);
    EXPECT_EQ(used_elem->len, sizeof(*send_response));
    EXPECT_EQ(send_response->type, VIRTIO_WL_RESP_OK);

    uint32_t pipe_data;
    size_t actual_bytes;
    ASSERT_EQ(socket.read(0, &pipe_data, sizeof(pipe_data), &actual_bytes), ZX_OK);
    EXPECT_EQ(actual_bytes, sizeof(pipe_data));
    EXPECT_EQ(pipe_data, 1234u);
  }

  channels_.clear();
}

TEST_F(VirtioWlTest, Hup) {
  ASSERT_EQ(CreateConnection(1u), ZX_OK);
  RunLoopUntilIdle();
  ASSERT_EQ(channels_.size(), 1u);

  // Close remote side of channel.
  channels_.clear();
  RunLoopUntilIdle();

  virtio_wl_ctrl_vfd_t* header;
  uint16_t descriptor_id;
  ASSERT_EQ(DescriptorChainBuilder(in_queue_)
                .AppendWritableDescriptor(&header, sizeof(*header))
                .Build(&descriptor_id),
            ZX_OK);

  ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_IN), ZX_OK);
  auto used_elem = NextUsed(&in_queue_);
  EXPECT_TRUE(used_elem);
  EXPECT_EQ(used_elem->id, descriptor_id);
  EXPECT_EQ(used_elem->len, sizeof(*header));
  EXPECT_EQ(header->hdr.type, VIRTIO_WL_CMD_VFD_HUP);
  EXPECT_EQ(header->hdr.flags, 0u);
  EXPECT_EQ(header->vfd_id, 1u);
}

TEST_F(VirtioWlTest, ImportExportImage) {
  ASSERT_EQ(CreateConnection(1u), ZX_OK);
  RunLoopUntilIdle();
  ASSERT_EQ(channels_.size(), 1u);
  fuchsia::virtualization::hardware::VirtioWaylandImporterSyncPtr importer;
  ASSERT_EQ(wl_->GetImporter(importer.NewRequest()), ZX_OK);

  virtio_wl_ctrl_vfd_new_t* new_vfd_cmd;
  uint16_t descriptor_id;
  ASSERT_EQ(DescriptorChainBuilder(in_queue_)
                .AppendWritableDescriptor(&new_vfd_cmd, sizeof(virtio_wl_ctrl_vfd_new_t))
                .Build(&descriptor_id),
            ZX_OK);

  uint32_t vfd_id = 0;
  uint64_t koid = 0;
  {
    fuchsia::virtualization::hardware::VirtioImage image;
    ASSERT_EQ(zx::vmo::create(kImportVmoSize, 0u, &image.vmo), ZX_OK);
    zx_info_handle_basic_t info;
    ASSERT_EQ(image.vmo.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr),
              ZX_OK);
    koid = info.koid;
    ASSERT_EQ(importer->ImportImage(std::move(image), &vfd_id), ZX_OK);
    ASSERT_NE(vfd_id, 0u);
  }
  {
    std::unique_ptr<fuchsia::virtualization::hardware::VirtioImage> image;
    zx_status_t result;
    ASSERT_EQ(importer->ExportImage(vfd_id, &result, &image), ZX_OK);
    ASSERT_TRUE(image);
    EXPECT_EQ(result, ZX_OK);
    zx_info_handle_basic_t info;
    ASSERT_EQ(image->vmo.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr),
              ZX_OK);
    EXPECT_EQ(koid, info.koid);
  }
}

TEST_F(VirtioWlTest, ImportExportImageWithToken) {
  ASSERT_EQ(CreateConnection(1u), ZX_OK);
  RunLoopUntilIdle();
  ASSERT_EQ(channels_.size(), 1u);
  fuchsia::virtualization::hardware::VirtioWaylandImporterSyncPtr importer;
  ASSERT_EQ(wl_->GetImporter(importer.NewRequest()), ZX_OK);

  virtio_wl_ctrl_vfd_new_t* new_vfd_cmd;
  uint16_t descriptor_id;
  ASSERT_EQ(DescriptorChainBuilder(in_queue_)
                .AppendWritableDescriptor(&new_vfd_cmd, sizeof(virtio_wl_ctrl_vfd_new_t))
                .Build(&descriptor_id),
            ZX_OK);

  uint32_t vfd_id = 0;
  uint64_t koid = 0;
  {
    fuchsia::virtualization::hardware::VirtioImage image;
    ASSERT_EQ(zx::vmo::create(kImportVmoSize, 0u, &image.vmo), ZX_OK);
    zx_info_handle_basic_t info;
    ASSERT_EQ(image.vmo.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr),
              ZX_OK);
    koid = info.koid;
    zx::eventpair ep;
    ASSERT_EQ(zx::eventpair::create(0, &ep, &image.token), ZX_OK);
    ASSERT_EQ(importer->ImportImage(std::move(image), &vfd_id), ZX_OK);
    ASSERT_NE(vfd_id, 0u);
  }
  {
    std::unique_ptr<fuchsia::virtualization::hardware::VirtioImage> image;
    zx_status_t result;
    ASSERT_EQ(importer->ExportImage(vfd_id, &result, &image), ZX_OK);
    ASSERT_TRUE(image);
    EXPECT_EQ(result, ZX_OK);
    zx_info_handle_basic_t info;
    ASSERT_EQ(image->vmo.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr),
              ZX_OK);
    EXPECT_EQ(koid, info.koid);
    ASSERT_EQ(image->token.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr),
              ZX_OK);
    EXPECT_EQ(info.type, ZX_OBJ_TYPE_EVENTPAIR);
  }
}

}  // namespace
