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

#include <fcntl.h>
#include <fuchsia/hardware/display/controller/c/banjo.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/fd.h>
#include <lib/fdio/io.h>
#include <lib/fidl/coding.h>
#include <lib/image-format-llcpp/image-format-llcpp.h>
#include <lib/stdcompat/optional.h>
#include <lib/zx/channel.h>
#include <lib/zx/vmo.h>
#include <string.h>
#include <zircon/assert.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>

#include <list>
#include <unordered_map>

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

#include "vc.h"

namespace fhd = fuchsia_hardware_display;
namespace sysmem = fuchsia_sysmem;

namespace {

// Arbitrary
constexpr uint32_t kSingleBufferStride = 4;

class StubDisplayController : public fidl::WireInterface<fhd::Controller> {
 public:
  StubDisplayController() {}

  virtual ~StubDisplayController() {}

  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 {
    EXPECT_TRUE(false);
  }
  void ReleaseImage(uint64_t image_id, ReleaseImageCompleter::Sync& _completer) override {
    images_.remove_if([image_id](uint64_t image) { return (image == image_id); });
  }
  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 {
    layers_.push_back(next_layer_);
    _completer.Reply(ZX_OK, next_layer_++);
  }

  void DestroyLayer(uint64_t layer_id, DestroyLayerCompleter::Sync& _completer) override {
    layers_.remove_if([layer_id](uint64_t layer) { return (layer == layer_id); });
  }

  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 {
    // Ignore
  }

  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 {
    _completer.Reply(fhd::wire::ConfigResult::kOk,
                     fidl::VectorView<fhd::wire::ClientCompositionOp>());
  }

  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,
                              fidl::ClientEnd<sysmem::BufferCollectionToken> collection_token,
                              ImportBufferCollectionCompleter::Sync& _completer) override {
    EXPECT_TRUE(false);
  }
  void ReleaseBufferCollection(uint64_t collection_id,
                               ReleaseBufferCollectionCompleter::Sync& _completer) override {}

  void SetBufferCollectionConstraints(
      uint64_t collection_id, fhd::wire::ImageConfig config,
      SetBufferCollectionConstraintsCompleter::Sync& _completer) override {
    EXPECT_TRUE(false);
  }

  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 SetMinimumRgb(uint8_t minimum_rgb, SetMinimumRgbCompleter::Sync& _completer) override {
    EXPECT_TRUE(false);
  }

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

  const std::list<uint64_t>& images() const { return images_; }
  const std::list<uint64_t>& layers() const { return layers_; }

  const std::unordered_map<uint64_t,
                           std::unique_ptr<fidl::WireSyncClient<sysmem::BufferCollection>>>&
  buffer_collections() const {
    return buffer_collections_;
  }

 protected:
  std::list<uint64_t> images_;
  uint64_t next_image_ = 1;
  // We want to make sure that we destroy every layer we create.
  std::list<uint64_t> layers_;
  uint64_t next_layer_ = 1;

  std::unordered_map<uint64_t, std::unique_ptr<fidl::WireSyncClient<sysmem::BufferCollection>>>
      buffer_collections_;
};

class StubSingleBufferDisplayController : public StubDisplayController {
 public:
  void ImportVmoImage(fhd::wire::ImageConfig image_config, ::zx::vmo vmo, int32_t offset,
                      ImportVmoImageCompleter::Sync& _completer) override {
    EXPECT_NE(ZX_HANDLE_INVALID, vmo.get());
    images_.push_back(next_image_);
    _completer.Reply(ZX_OK, next_image_++);
  }
  void GetSingleBufferFramebuffer(GetSingleBufferFramebufferCompleter::Sync& _completer) override {
    zx::vmo vmo;
    zx::vmo::create(4096, 0, &vmo);
    _completer.Reply(ZX_OK, std::move(vmo), kSingleBufferStride);
  }
};

class StubMultiBufferDisplayController : public StubDisplayController {
 public:
  void GetSingleBufferFramebuffer(GetSingleBufferFramebufferCompleter::Sync& _completer) override {
    _completer.Reply(ZX_ERR_NOT_SUPPORTED, zx::vmo(), 0);
  }
  void ImportImage(fhd::wire::ImageConfig image_config, uint64_t collection_id, uint32_t index,
                   ImportImageCompleter::Sync& _completer) override {
    images_.push_back(next_image_);
    _completer.Reply(ZX_OK, next_image_++);
  }

  void ImportBufferCollection(uint64_t collection_id,
                              fidl::ClientEnd<sysmem::BufferCollectionToken> collection_token,
                              ImportBufferCollectionCompleter::Sync& _completer) override {
    auto endpoints = fidl::CreateEndpoints<sysmem::BufferCollection>();
    ASSERT_OK(endpoints.status_value());
    ASSERT_OK(get_sysmem_allocator()
                  ->BindSharedCollection(std::move(collection_token), std::move(endpoints->server))
                  .status());
    buffer_collections_[collection_id] =
        std::make_unique<fidl::WireSyncClient<sysmem::BufferCollection>>(
            fidl::BindSyncClient(std::move(endpoints->client)));

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

  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 = 2;
    for (uint32_t i = 0; i < 2; i++) {
      auto& image_constraints = constraints.image_format_constraints[i];
      image_constraints = image_format::GetDefaultImageFormatConstraints();
      if (i == 0) {
        image_constraints.pixel_format.type = sysmem::wire::PixelFormatType::kBgra32;
      } else {
        image_constraints.pixel_format.type = sysmem::wire::PixelFormatType::kRgb565;
      }
      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.max_bytes_per_row = 0xffffffff;
      image_constraints.bytes_per_row_divisor = 4;
    }

    buffer_collections_[collection_id]->SetConstraints(true, constraints);
    _completer.Reply(ZX_OK);
  }
};
}  // namespace

zx_status_t log_create_vc(vc_gfx_t* graphics, vc_t** vc_out) { return ZX_OK; }

void log_delete_vc(vc_t* vc) {}

void set_log_listener_active(bool active) {}

void vc_attach_gfx(vc_t* vc) {}

zx_status_t vc_init_gfx(vc_gfx_t* gfx, zx_handle_t fb_vmo, int32_t width, int32_t height,
                        zx_pixel_format_t format, int32_t stride) {
  return ZX_OK;
}

void vc_change_graphics(vc_gfx_t* graphics) {}

class VcDisplayTest : public zxtest::Test {
  void SetUp() override { ASSERT_TRUE(vc_sysmem_connect()); }

  void TearDown() override {
    if (loop_) {
      // Ensure the loop processes all queued FIDL messages.
      loop_->Quit();
      loop_->JoinThreads();
      loop_->ResetQuit();
      loop_->RunUntilIdle();
    }

    loop_.reset();
    if (controller_) {
      ASSERT_EQ(controller_->layers().size(), 0);
      ASSERT_EQ(controller_->images().size(), 0);
      ASSERT_EQ(controller_->buffer_collections().size(), 0u);
    }
    controller_.reset();
  }

 protected:
  void InitializeServer() {
    auto endpoints = fidl::CreateEndpoints<fhd::Controller>();
    ASSERT_OK(endpoints.status_value());
    initialize_display_channel(std::move(endpoints->client));
    loop_ = std::make_unique<async::Loop>(&kAsyncLoopConfigNoAttachToCurrentThread);
    loop_->StartThread();

    server_binding_ =
        fidl::BindServer(loop_->dispatcher(), std::move(endpoints->server), controller_.get());
  }
  void SendAddDisplay(fhd::wire::Info* display) {
    server_binding_.value()->OnDisplaysChanged(
        fidl::VectorView<fhd::wire::Info>::FromExternal(display, 1), fidl::VectorView<uint64_t>());
  }
  void SendRemoveDisplay(uint64_t id) {
    server_binding_.value()->OnDisplaysChanged(fidl::VectorView<fhd::wire::Info>(),
                                               fidl::VectorView<uint64_t>::FromExternal(&id, 1));
  }

  void ProcessEvent() { ASSERT_OK(dc_callback_handler(ZX_CHANNEL_READABLE)); }

  std::unique_ptr<StubDisplayController> controller_;

  // Loop needs to be torn down before controller, because that causes the
  // binding to close.
  std::unique_ptr<async::Loop> loop_;

  // Server binding reference used to send events.
  cpp17::optional<fidl::ServerBindingRef<fhd::Controller>> server_binding_;
};

TEST_F(VcDisplayTest, EmptyRebind) { ASSERT_EQ(rebind_display(true), ZX_ERR_NO_RESOURCES); }

TEST_F(VcDisplayTest, OneDisplay) {
  controller_ = std::make_unique<StubSingleBufferDisplayController>();
  InitializeServer();

  fhd::wire::Info info;
  info.id = 1;
  uint32_t format = 0x0;
  fhd::wire::Mode mode;
  info.modes = fidl::VectorView<fhd::wire::Mode>::FromExternal(&mode, 1);
  info.pixel_format = fidl::VectorView<uint32_t>::FromExternal(&format, 1);

  SendAddDisplay(&info);
  ProcessEvent();
  ASSERT_TRUE(is_primary_bound());
  display_info_t* primary = list_peek_head_type(get_display_list(), display_info_t, node);
  ASSERT_TRUE(primary->bound);

  handle_display_removed(1);
  ASSERT_FALSE(is_primary_bound());
}

TEST_F(VcDisplayTest, TwoDisplays) {
  controller_ = std::make_unique<StubSingleBufferDisplayController>();
  InitializeServer();

  fhd::wire::Info hardware_display;
  hardware_display.id = 1;
  uint32_t format = 0x0;
  fhd::wire::Mode mode;
  hardware_display.modes = fidl::VectorView<fhd::wire::Mode>::FromExternal(&mode, 1);
  hardware_display.pixel_format = fidl::VectorView<uint32_t>::FromExternal(&format, 1);

  // Add the first display.
  SendAddDisplay(&hardware_display);
  ProcessEvent();
  ASSERT_TRUE(is_primary_bound());

  display_info_t* primary = list_peek_head_type(get_display_list(), display_info_t, node);
  ASSERT_TRUE(primary->bound);

  // Add the second display.
  hardware_display.id = 2;
  SendAddDisplay(&hardware_display);
  ProcessEvent();
  ASSERT_TRUE(is_primary_bound());

  // Check that all of the displays were bound.
  display_info_t* info;
  int num_displays = 0;
  list_for_every_entry (get_display_list(), info, display_info_t, node) {
    ASSERT_TRUE(info->bound);
    num_displays++;
  }
  ASSERT_EQ(num_displays, 2);

  // Remove the second display.
  SendRemoveDisplay(2u);
  ProcessEvent();
  // handle_display_removed(2);
  ASSERT_TRUE(is_primary_bound());

  // Remove the first display.
  SendRemoveDisplay(1u);
  ProcessEvent();
  ASSERT_FALSE(is_primary_bound());
}

// This test checks that the primary display switches over correctly.
// It allocates display 1 and then display 2, then removes display 1.
// Display 2 should switch over to the primary display.
TEST_F(VcDisplayTest, ChangePrimaryDisplay) {
  controller_ = std::make_unique<StubSingleBufferDisplayController>();
  InitializeServer();

  fhd::wire::Info hardware_display;
  hardware_display.id = 1;
  uint32_t format = 0x0;
  fhd::wire::Mode mode;
  hardware_display.modes = fidl::VectorView<fhd::wire::Mode>::FromExternal(&mode, 1);
  hardware_display.pixel_format = fidl::VectorView<uint32_t>::FromExternal(&format, 1);

  // Add the first display.
  SendAddDisplay(&hardware_display);
  ProcessEvent();
  ASSERT_TRUE(is_primary_bound());

  display_info_t* primary = list_peek_head_type(get_display_list(), display_info_t, node);
  ASSERT_TRUE(primary->bound);

  // Add the second display.
  hardware_display.id = 2;
  SendAddDisplay(&hardware_display);
  ProcessEvent();
  ASSERT_TRUE(is_primary_bound());

  // Check that all of the displays were bound.
  display_info_t* info;
  int num_displays = 0;
  list_for_every_entry (get_display_list(), info, display_info_t, node) {
    ASSERT_TRUE(info->bound);
    num_displays++;
  }
  ASSERT_EQ(num_displays, 2);

  // Remove the first display.
  SendRemoveDisplay(1);
  ProcessEvent();
  ASSERT_TRUE(is_primary_bound());

  // Remove the second display.
  SendRemoveDisplay(2);
  ProcessEvent();
  ASSERT_FALSE(is_primary_bound());
}

TEST_F(VcDisplayTest, SingleBufferVmo) {
  controller_ = std::make_unique<StubSingleBufferDisplayController>();
  InitializeServer();

  fhd::wire::Info hardware_display;
  hardware_display.id = 1;
  uint32_t format = 0x0;
  fhd::wire::Mode mode;
  hardware_display.modes = fidl::VectorView<fhd::wire::Mode>::FromExternal(&mode, 1);
  hardware_display.pixel_format = fidl::VectorView<uint32_t>::FromExternal(&format, 1);

  // Add the first display.
  SendAddDisplay(&hardware_display);
  ProcessEvent();
  ASSERT_TRUE(is_primary_bound());

  display_info_t* primary = list_peek_head_type(get_display_list(), display_info_t, node);
  ASSERT_TRUE(primary->bound);
  EXPECT_EQ(1u, controller_->images().size());

  EXPECT_NE(ZX_HANDLE_INVALID, primary->image_vmo);
  EXPECT_EQ(kSingleBufferStride, primary->stride);

  SendRemoveDisplay(1);
  ProcessEvent();
}

class VcDisplayMultibufferTest : public VcDisplayTest {
 public:
  void SetupMode(zx_pixel_format_t format) {
    controller_ = std::make_unique<StubMultiBufferDisplayController>();
    InitializeServer();

    fhd::wire::Info hardware_display;
    hardware_display.id = 1;
    fhd::wire::Mode mode;
    mode.horizontal_resolution = 641;
    mode.vertical_resolution = 480;
    hardware_display.modes = fidl::VectorView<fhd::wire::Mode>::FromExternal(&mode, 1);
    hardware_display.pixel_format = fidl::VectorView<uint32_t>::FromExternal(&format, 1);

    // Add the first display.
    SendAddDisplay(&hardware_display);
    ProcessEvent();
    ASSERT_TRUE(is_primary_bound());
  }

  void TeardownDisplay() {
    SendRemoveDisplay(1);
    ProcessEvent();
  }
};

TEST_F(VcDisplayMultibufferTest, RGBA32) {
  SetupMode(ZX_PIXEL_FORMAT_ARGB_8888);
  display_info_t* primary = list_peek_head_type(get_display_list(), display_info_t, node);
  ASSERT_TRUE(primary->bound);
  EXPECT_EQ(primary->format, ZX_PIXEL_FORMAT_ARGB_8888);

  EXPECT_NE(ZX_HANDLE_INVALID, primary->image_vmo);
  EXPECT_EQ(641, primary->stride);
  TeardownDisplay();
}

TEST_F(VcDisplayMultibufferTest, RGB565) {
  SetupMode(ZX_PIXEL_FORMAT_RGB_565);
  display_info_t* primary = list_peek_head_type(get_display_list(), display_info_t, node);
  ASSERT_TRUE(primary->bound);

  EXPECT_EQ(primary->format, ZX_PIXEL_FORMAT_RGB_565);

  EXPECT_NE(ZX_HANDLE_INVALID, primary->image_vmo);
  // Stride should be rounded up to be a multiple of 4 bytes.
  EXPECT_EQ(642, primary->stride);
  TeardownDisplay();
}
