// 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 <virtio/gpu.h>

#include "garnet/bin/guest/vmm/device/gpu.h"
#include "garnet/bin/guest/vmm/device/test_with_device.h"
#include "garnet/bin/guest/vmm/device/virtio_queue_fake.h"

static constexpr char kVirtioGpuUrl[] =
    "fuchsia-pkg://fuchsia.com/virtio_gpu#meta/virtio_gpu.cmx";
static constexpr uint16_t kNumQueues = 2;
static constexpr uint16_t kQueueSize = 16;

static constexpr uint32_t kPixelFormat = VIRTIO_GPU_FORMAT_B8G8R8A8_UNORM;
static constexpr uint32_t kResourceId = 0;
static constexpr uint32_t kScanoutId = 0;

class VirtioGpuTest : public TestWithDevice {
 protected:
  VirtioGpuTest()
      : control_queue_(phys_mem_, PAGE_SIZE * kNumQueues, kQueueSize),
        cursor_queue_(phys_mem_, control_queue_.end(), kQueueSize) {}

  void SetUp() override {
    // Launch device process.
    fuchsia::guest::device::StartInfo start_info;
    zx_status_t status =
        LaunchDevice(kVirtioGpuUrl, cursor_queue_.end(), &start_info);
    ASSERT_EQ(ZX_OK, status);

    // Start device execution.
    services.ConnectToService(gpu_.NewRequest());
    status = gpu_->Start(std::move(start_info), nullptr);
    ASSERT_EQ(ZX_OK, status);

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

  void ResourceCreate2d() {
    virtio_gpu_resource_create_2d_t request = {
        .hdr = {.type = VIRTIO_GPU_CMD_RESOURCE_CREATE_2D},
        .format = kPixelFormat,
        .resource_id = kResourceId,
        .width = kGpuStartupWidth,
        .height = kGpuStartupHeight,
    };
    virtio_gpu_ctrl_hdr_t* response;
    zx_status_t status =
        DescriptorChainBuilder(control_queue_)
            .AppendReadableDescriptor(&request, sizeof(request))
            .AppendWritableDescriptor(&response, sizeof(*response))
            .Build();
    ASSERT_EQ(ZX_OK, status);

    status = gpu_->NotifyQueue(0);
    ASSERT_EQ(ZX_OK, status);
    status = WaitOnInterrupt();
    ASSERT_EQ(ZX_OK, status);

    ASSERT_EQ(VIRTIO_GPU_RESP_OK_NODATA, response->type);
  }

  void ResourceAttachBacking() {
    virtio_gpu_resource_attach_backing_t request = {
        .hdr = {.type = VIRTIO_GPU_CMD_RESOURCE_ATTACH_BACKING},
        .resource_id = kResourceId,
        .nr_entries = 0,
    };
    virtio_gpu_ctrl_hdr_t* response;
    zx_status_t status =
        DescriptorChainBuilder(control_queue_)
            .AppendReadableDescriptor(&request, sizeof(request))
            .AppendWritableDescriptor(&response, sizeof(*response))
            .Build();
    ASSERT_EQ(ZX_OK, status);

    status = gpu_->NotifyQueue(0);
    ASSERT_EQ(ZX_OK, status);
    status = WaitOnInterrupt();
    ASSERT_EQ(ZX_OK, status);

    ASSERT_EQ(VIRTIO_GPU_RESP_OK_NODATA, response->type);
  }

  void SetScanout(uint32_t resource_id, uint32_t response_type) {
    virtio_gpu_set_scanout_t request = {
        .hdr = {.type = VIRTIO_GPU_CMD_SET_SCANOUT},
        .resource_id = resource_id,
        .scanout_id = kScanoutId,
        .r = {.x = 0,
              .y = 0,
              .width = kGpuStartupWidth,
              .height = kGpuStartupHeight},
    };
    virtio_gpu_ctrl_hdr_t* response;
    zx_status_t status =
        DescriptorChainBuilder(control_queue_)
            .AppendReadableDescriptor(&request, sizeof(request))
            .AppendWritableDescriptor(&response, sizeof(*response))
            .Build();
    ASSERT_EQ(ZX_OK, status);

    status = gpu_->NotifyQueue(0);
    ASSERT_EQ(ZX_OK, status);
    status = WaitOnInterrupt();
    ASSERT_EQ(ZX_OK, status);

    EXPECT_EQ(response_type, response->type);
  }

  fuchsia::guest::device::VirtioGpuSyncPtr gpu_;
  VirtioQueueFake control_queue_;
  VirtioQueueFake cursor_queue_;
};

TEST_F(VirtioGpuTest, GetDisplayInfo) {
  virtio_gpu_ctrl_hdr_t request = {
      .type = VIRTIO_GPU_CMD_GET_DISPLAY_INFO,
  };
  virtio_gpu_resp_display_info_t* response;
  zx_status_t status =
      DescriptorChainBuilder(control_queue_)
          .AppendReadableDescriptor(&request, sizeof(request))
          .AppendWritableDescriptor(&response, sizeof(*response))
          .Build();
  ASSERT_EQ(ZX_OK, status);

  status = gpu_->NotifyQueue(0);
  ASSERT_EQ(ZX_OK, status);
  status = WaitOnInterrupt();
  ASSERT_EQ(ZX_OK, status);

  EXPECT_EQ(response->hdr.type, VIRTIO_GPU_RESP_OK_DISPLAY_INFO);
  EXPECT_EQ(response->pmodes[0].r.x, 0u);
  EXPECT_EQ(response->pmodes[0].r.y, 0u);
  EXPECT_EQ(response->pmodes[0].r.width, kGpuStartupWidth);
  EXPECT_EQ(response->pmodes[0].r.height, kGpuStartupHeight);
}

TEST_F(VirtioGpuTest, SetScanout) {
  ResourceCreate2d();
  ResourceAttachBacking();
  SetScanout(kResourceId, VIRTIO_GPU_RESP_OK_NODATA);
}

TEST_F(VirtioGpuTest, SetScanoutWithInvalidResourceId) {
  ResourceCreate2d();
  ResourceAttachBacking();
  SetScanout(UINT32_MAX, VIRTIO_GPU_RESP_ERR_INVALID_RESOURCE_ID);
}
