// 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>

#include "src/lib/fsl/handles/object_info.h"

namespace fhd = fuchsia_hardware_display;
namespace sysmem = 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;
    }
    ASSERT_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 fidl::WireRawChannelInterface<fhd::Controller> {
 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<fidl::WireSyncClient<sysmem::Allocator>>(std::move(sysmem_client));
    sysmem_allocator_->SetDebugClientInfo(
        fidl::StringView::FromExternal(fsl::GetCurrentProcessName() + "-debug-client"),
        fsl::GetCurrentProcessKoid());
  }

  ~StubDisplayController() { current_buffer_collection_->Close(); }
  void ImportVmoImage(fhd::wire::ImageConfig image_config, ::zx::vmo vmo, int32_t offset,
                      ImportVmoImageCompleter::Sync& _completer) override {
    EXPECT_TRUE(false);
  }
  void ImportImage(fhd::wire::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 ImportGammaTable(uint64_t gamma_table_id, ::fidl::Array<float, 256> r,
                        ::fidl::Array<float, 256> g, ::fidl::Array<float, 256> b,
                        ImportGammaTableCompleter::Sync& _completer) override {
    EXPECT_TRUE(false);
  }

  void ReleaseGammaTable(uint64_t gamma_table_id,
                         ReleaseGammaTableCompleter::Sync& _completer) override {
    EXPECT_TRUE(false);
  }

  void SetDisplayMode(uint64_t display_id, fhd::wire::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 SetDisplayGammaTable(uint64_t display_id, uint64_t gamma_table_id,
                            SetDisplayGammaTableCompleter::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::wire::ImageConfig image_config,
                             SetLayerPrimaryConfigCompleter::Sync& _completer) override {
    // Ignore
  }

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

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

  void SetLayerCursorConfig(uint64_t layer_id, fhd::wire::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<fidl::WireSyncClient<sysmem::BufferCollection>>(std::move(client));

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

  void SetBufferCollectionConstraints(
      uint64_t collection_id, fhd::wire::ImageConfig config,
      SetBufferCollectionConstraintsCompleter::Sync& _completer) override {
    sysmem::wire::BufferCollectionConstraints constraints;
    constraints.usage.cpu = sysmem::wire::kCpuUsageWriteOften | sysmem::wire::kCpuUsageRead;
    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::wire::PixelFormatType::kBgra32;
    image_constraints.pixel_format.has_format_modifier = true;
    image_constraints.pixel_format.format_modifier.value = sysmem::wire::kFormatModifierLinear;
    image_constraints.color_spaces_count = 1;
    image_constraints.color_space[0].type = sysmem::wire::ColorSpaceType::kSrgb;
    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::wire::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);
  }

  void AcknowledgeVsync(uint64_t cookie, AcknowledgeVsyncCompleter::Sync& _completer) override {
    EXPECT_TRUE(false);
  }

  void SetMinimumRgb(uint8_t minimum_rgb, SetMinimumRgbCompleter::Sync& _completer) override {
    EXPECT_TRUE(false);
  }

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

}  // namespace

void SendInitialDisplay(const fidl::WireEventSender<fhd::Controller>& event_sender,
                        fhd::wire::Mode* mode, uint32_t pixel_format) {
  fhd::wire::Info info;
  info.pixel_format = fidl::VectorView<uint32_t>::FromExternal(&pixel_format, 1);
  info.modes = fidl::VectorView<fhd::wire::Mode>::FromExternal(mode, 1);
  auto added = fidl::VectorView<fhd::wire::Info>::FromExternal(&info, 1);
  fidl::VectorView<uint64_t> removed;

  ASSERT_OK(event_sender.OnDisplaysChanged(std::move(added), std::move(removed)));
}

void TestDisplayStride(bool ram_domain) {
  zx::channel server_channel, client_channel;
  ASSERT_OK(zx::channel::create(0u, &server_channel, &client_channel));
  fidl::WireEventSender<fhd::Controller> event_sender(std::move(server_channel));

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

  loop.StartThread();

  ASSERT_OK(fidl::BindSingleInFlightOnly(loop.dispatcher(), std::move(event_sender.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); }
