// 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/framebuffer/framebuffer.h"

#include <fcntl.h>
#include <fuchsia/hardware/display/llcpp/fidl.h>
#include <fuchsia/sysmem/llcpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fdio/directory.h>
#include <lib/fidl-async/cpp/bind.h>
#include <lib/image-format-llcpp/image-format-llcpp.h>
#include <zircon/pixelformat.h>

#include <thread>

#include <fbl/unique_fd.h>
#include <zxtest/zxtest.h>

namespace fhd = llcpp::fuchsia::hardware::display;
namespace sysmem = ::llcpp::fuchsia::sysmem;

zx_status_t fb_bind_with_channel(bool single_buffer, const char** err_msg_out,
                                 zx::channel dc_client_channel);

void RunSingleBufferTest() {
  fbl::unique_fd dc_fd(open("/dev/class/display-controller/000", O_RDWR));
  if (!dc_fd) {
    fprintf(stdout, "Skipping test because of no display controller\n");
    return;
  }
  dc_fd.reset();
  constexpr uint32_t kIterations = 2;

  for (uint32_t i = 0; i < kIterations; i++) {
    const char* error;
    zx_status_t status = fb_bind(true, &error);
    if (status == ZX_ERR_NOT_SUPPORTED) {
      // If the simple display driver is being used then sysmem isn't supported
      // and libframebuffer isn't either.
      fprintf(stderr, "Skipping because received ZX_ERR_NOT_SUPPORTED\n");
      return;
    }
    EXPECT_OK(status);
    zx_handle_t buffer_handle = fb_get_single_buffer();
    EXPECT_NE(ZX_HANDLE_INVALID, buffer_handle);

    uint32_t width, height, linear_stride_px;
    zx_pixel_format_t format;
    fb_get_config(&width, &height, &linear_stride_px, &format);
    EXPECT_LE(width, linear_stride_px);
    EXPECT_LT(0u, ZX_PIXEL_FORMAT_BYTES(format));

    uint64_t buffer_size;
    EXPECT_OK(zx_vmo_get_size(buffer_handle, &buffer_size));
    EXPECT_LE(linear_stride_px * ZX_PIXEL_FORMAT_BYTES(format) * height, buffer_size);

    fb_release();
  }
}

TEST(Framebuffer, SingleBuffer) {
  zx::event finished;
  zx::event::create(0, &finished);
  std::thread execute_thread([&finished]() {
    RunSingleBufferTest();
    finished.signal(0, ZX_USER_SIGNAL_0);
  });
  zx_status_t status =
      finished.wait_one(ZX_USER_SIGNAL_0, zx::deadline_after(zx::sec(60)), nullptr);
  EXPECT_EQ(ZX_OK, status);
  if (status != ZX_OK) {
    fprintf(stderr, "Test timed out. Maybe no display is connected to device.\n");
    execute_thread.detach();
  } else {
    execute_thread.join();
  }
}

namespace {

constexpr uint32_t kBytesPerRowDivisor = 128;

class StubDisplayController : public fhd::Controller::Interface {
 public:
  StubDisplayController(bool use_ram_domain) : use_ram_domain_(use_ram_domain) {
    zx::channel sysmem_server, sysmem_client;
    ASSERT_OK(zx::channel::create(0, &sysmem_server, &sysmem_client));
    ASSERT_OK(fdio_service_connect("/svc/fuchsia.sysmem.Allocator", sysmem_server.release()));

    sysmem_allocator_ = std::make_unique<sysmem::Allocator::SyncClient>(std::move(sysmem_client));
  }

  ~StubDisplayController() { current_buffer_collection_->Close(); }
  void ImportVmoImage(fhd::ImageConfig image_config, ::zx::vmo vmo, int32_t offset,
                      ImportVmoImageCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }
  void ImportImage(fhd::ImageConfig image_config, uint64_t collection_id, uint32_t index,
                   ImportImageCompleter::Sync _completer) override {
    _completer.Reply(ZX_OK, 1);
  }
  void ReleaseImage(uint64_t image_id, ReleaseImageCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }
  void ImportEvent(::zx::event event, uint64_t id, ImportEventCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }
  void ReleaseEvent(uint64_t id, ReleaseEventCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }
  void CreateLayer(CreateLayerCompleter::Sync _completer) override { _completer.Reply(ZX_OK, 1); }

  void DestroyLayer(uint64_t layer_id, DestroyLayerCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }
  void SetDisplayMode(uint64_t display_id, fhd::Mode mode,
                      SetDisplayModeCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }
  void SetDisplayColorConversion(uint64_t display_id, ::fidl::Array<float, 3> preoffsets,
                                 ::fidl::Array<float, 9> coefficients,
                                 ::fidl::Array<float, 3> postoffsets,
                                 SetDisplayColorConversionCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }

  void SetDisplayLayers(uint64_t display_id, ::fidl::VectorView<uint64_t> layer_ids,
                        SetDisplayLayersCompleter::Sync _completer) override {
    // Ignore
  }

  void SetLayerPrimaryConfig(uint64_t layer_id, fhd::ImageConfig image_config,
                             SetLayerPrimaryConfigCompleter::Sync _completer) override {
    // Ignore
  }

  void SetLayerPrimaryPosition(uint64_t layer_id, fhd::Transform transform, fhd::Frame src_frame,
                               fhd::Frame dest_frame,
                               SetLayerPrimaryPositionCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }

  void SetLayerPrimaryAlpha(uint64_t layer_id, fhd::AlphaMode mode, float val,
                            SetLayerPrimaryAlphaCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }

  void SetLayerCursorConfig(uint64_t layer_id, fhd::ImageConfig image_config,
                            SetLayerCursorConfigCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }

  void SetLayerCursorPosition(uint64_t layer_id, int32_t x, int32_t y,
                              SetLayerCursorPositionCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }

  void SetLayerColorConfig(uint64_t layer_id, uint32_t pixel_format,
                           ::fidl::VectorView<uint8_t> color_bytes,
                           SetLayerColorConfigCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }

  void SetLayerImage(uint64_t layer_id, uint64_t image_id, uint64_t wait_event_id,
                     uint64_t signal_event_id, SetLayerImageCompleter::Sync _completer) override {
    // Ignore
  }

  void CheckConfig(bool discard, CheckConfigCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }

  void ApplyConfig(ApplyConfigCompleter::Sync _completer) override {
    // Ignore
  }

  void EnableVsync(bool enable, EnableVsyncCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }

  void SetVirtconMode(uint8_t mode, SetVirtconModeCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }

  void ImportBufferCollection(uint64_t collection_id, ::zx::channel collection_token,
                              ImportBufferCollectionCompleter::Sync _completer) override {
    zx::channel server, client;
    ASSERT_OK(zx::channel::create(0, &server, &client));

    ASSERT_TRUE(
        sysmem_allocator_->BindSharedCollection(std::move(collection_token), std::move(server))
            .ok());
    current_buffer_collection_ =
        std::make_unique<sysmem::BufferCollection::SyncClient>(std::move(client));

    _completer.Reply(ZX_OK);
  }
  void ReleaseBufferCollection(uint64_t collection_id,
                               ReleaseBufferCollectionCompleter::Sync _completer) override {}

  void SetBufferCollectionConstraints(
      uint64_t collection_id, fhd::ImageConfig config,
      SetBufferCollectionConstraintsCompleter::Sync _completer) override {
    sysmem::BufferCollectionConstraints constraints;
    constraints.usage.cpu = sysmem::cpuUsageWriteOften | sysmem::cpuUsageRead;
    constraints.min_buffer_count = 1;
    constraints.image_format_constraints_count = 1;
    auto& image_constraints = constraints.image_format_constraints[0];
    image_constraints = image_format::GetDefaultImageFormatConstraints();
    image_constraints.pixel_format.type = sysmem::PixelFormatType::BGRA32;
    image_constraints.pixel_format.has_format_modifier = true;
    image_constraints.pixel_format.format_modifier.value = sysmem::FORMAT_MODIFIER_LINEAR;
    image_constraints.color_spaces_count = 1;
    image_constraints.color_space[0].type = sysmem::ColorSpaceType::SRGB;
    image_constraints.max_coded_width = 0xffffffff;
    image_constraints.max_coded_height = 0xffffffff;
    image_constraints.min_bytes_per_row = 0;
    image_constraints.max_bytes_per_row = 0xffffffff;
    image_constraints.bytes_per_row_divisor = kBytesPerRowDivisor;

    constraints.has_buffer_memory_constraints = true;
    constraints.buffer_memory_constraints = image_format::GetDefaultBufferMemoryConstraints();
    constraints.buffer_memory_constraints.ram_domain_supported = use_ram_domain_;
    constraints.buffer_memory_constraints.cpu_domain_supported = !use_ram_domain_;

    current_buffer_collection_->SetConstraints(true, constraints);
    _completer.Reply(ZX_OK);
  }

  void GetSingleBufferFramebuffer(GetSingleBufferFramebufferCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }

  void IsCaptureSupported(IsCaptureSupportedCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }

  void ImportImageForCapture(fhd::ImageConfig image_config, uint64_t collection_id, uint32_t index,
                             ImportImageForCaptureCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }

  void StartCapture(uint64_t signal_event_id, uint64_t image_id,
                    StartCaptureCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }

  void ReleaseCapture(uint64_t image_id, ReleaseCaptureCompleter::Sync _completer) override {
    EXPECT_TRUE(false);
  }

 private:
  std::unique_ptr<sysmem::Allocator::SyncClient> sysmem_allocator_;
  std::unique_ptr<sysmem::BufferCollection::SyncClient> current_buffer_collection_;
  bool use_ram_domain_;
};

}  // namespace

void SendInitialDisplay(const zx::channel& server_channel, fhd::Mode* mode, uint32_t pixel_format) {
  fhd::Info info;
  info.pixel_format = fidl::VectorView(&pixel_format, 1);
  info.modes = fidl::VectorView(mode, 1);
  fidl::VectorView<fhd::Info> added(&info, 1);
  fidl::VectorView<uint64_t> removed;

  ASSERT_OK(fhd::Controller::SendDisplaysChangedEvent(zx::unowned_channel(server_channel), added,
                                                      removed));
}

void TestDisplayStride(bool ram_domain) {
  zx::channel server_channel, client_channel;
  ASSERT_OK(zx::channel::create(0u, &server_channel, &client_channel));

  StubDisplayController controller(ram_domain);
  async::Loop loop(&kAsyncLoopConfigNoAttachToCurrentThread);
  fhd::Mode mode;
  mode.horizontal_resolution = 301;
  mode.vertical_resolution = 250;
  constexpr uint32_t kPixelFormat = ZX_PIXEL_FORMAT_ARGB_8888;
  SendInitialDisplay(server_channel, &mode, kPixelFormat);

  loop.StartThread();

  ASSERT_OK(fidl::Bind(loop.dispatcher(), std::move(server_channel), &controller));

  const char* error;
  zx_status_t status = fb_bind_with_channel(true, &error, std::move(client_channel));
  EXPECT_OK(status);
  zx_handle_t buffer_handle = fb_get_single_buffer();
  EXPECT_NE(ZX_HANDLE_INVALID, buffer_handle);

  uint32_t width, height, linear_stride_px;
  zx_pixel_format_t format;
  fb_get_config(&width, &height, &linear_stride_px, &format);
  EXPECT_EQ(mode.horizontal_resolution, width);
  EXPECT_EQ(mode.vertical_resolution, height);
  EXPECT_EQ(kPixelFormat, format);

  constexpr uint32_t kBytesPerPixel = 4;

  // Round up to be a multiple of kBytesPerRowDivisor bytes.
  EXPECT_EQ(fbl::round_up(width * kBytesPerPixel, kBytesPerRowDivisor) / kBytesPerPixel,
            linear_stride_px);

  uint64_t buffer_size;
  EXPECT_OK(zx_vmo_get_size(buffer_handle, &buffer_size));
  EXPECT_LE(linear_stride_px * ZX_PIXEL_FORMAT_BYTES(format) * height, buffer_size);
}

// Check that the correct stride is returned when a weird one is used.
TEST(Framebuffer, DisplayStrideCpuDomain) { TestDisplayStride(false); }

TEST(Framebuffer, DisplayStrideRamDomain) { TestDisplayStride(true); }
