// 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 "src/graphics/display/drivers/amlogic-display/display-engine.h"

#include <fidl/fuchsia.images2/cpp/wire.h>
#include <fidl/fuchsia.sysmem2/cpp/wire_test_base.h>
#include <fuchsia/hardware/display/controller/c/banjo.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/default.h>
#include <lib/async_patterns/testing/cpp/dispatcher_bound.h>
#include <lib/inspect/cpp/inspect.h>

#include <fake-mmio-reg/fake-mmio-reg.h>
#include <gtest/gtest.h>

#include "fidl/fuchsia.images2/cpp/wire_types.h"
#include "fidl/fuchsia.sysmem2/cpp/wire_types.h"
#include "lib/fidl/cpp/wire/arena.h"
#include "src/devices/testing/mock-ddk/mock-device.h"
#include "src/graphics/display/drivers/amlogic-display/pixel-grid-size2d.h"
#include "src/graphics/display/drivers/amlogic-display/video-input-unit.h"
#include "src/graphics/display/lib/api-types-cpp/driver-buffer-collection-id.h"
#include "src/graphics/display/lib/driver-framework-migration-utils/dispatcher/loop-backed-dispatcher-factory.h"
#include "src/graphics/display/lib/driver-framework-migration-utils/metadata/metadata-getter-dfv1.h"
#include "src/graphics/display/lib/driver-framework-migration-utils/metadata/metadata-getter.h"
#include "src/graphics/display/lib/driver-framework-migration-utils/namespace/namespace-dfv1.h"
#include "src/lib/fsl/handles/object_info.h"
#include "src/lib/testing/predicates/status.h"

namespace amlogic_display {

namespace {

// TODO(https://fxbug.dev/42072949): Consider creating and using a unified set of sysmem
// testing doubles instead of writing mocks for each display driver test.
class MockBufferCollectionBase
    : public fidl::testing::WireTestBase<fuchsia_sysmem2::BufferCollection> {
 public:
  MockBufferCollectionBase() = default;
  ~MockBufferCollectionBase() override = default;

  virtual void VerifyBufferCollectionConstraints(
      const fuchsia_sysmem2::wire::BufferCollectionConstraints& constraints) = 0;
  virtual void VerifyName(const std::string& name) = 0;

  void SetConstraints(SetConstraintsRequestView request,
                      SetConstraintsCompleter::Sync& completer) override {
    if (!request->has_constraints()) {
      return;
    }
    VerifyBufferCollectionConstraints(request->constraints());
    set_constraints_called_ = true;
  }

  void SetName(SetNameRequestView request, SetNameCompleter::Sync& completer) override {
    EXPECT_EQ(10u, request->priority());
    VerifyName(std::string(request->name().data(), request->name().size()));
    set_name_called_ = true;
  }

  void CheckAllBuffersAllocated(CheckAllBuffersAllocatedCompleter::Sync& completer) override {
    completer.Reply(fit::ok());
  }

  void WaitForAllBuffersAllocated(WaitForAllBuffersAllocatedCompleter::Sync& completer) override {
    zx::vmo vmo;
    EXPECT_EQ(ZX_OK, zx::vmo::create(ZX_PAGE_SIZE, 0u, &vmo));
    auto collection = fuchsia_sysmem2::wire::BufferCollectionInfo::Builder(arena_)
                          .buffers(std::vector{fuchsia_sysmem2::wire::VmoBuffer::Builder(arena_)
                                                   .vmo(std::move(vmo))
                                                   .vmo_usable_start(0)
                                                   .Build()})
                          .settings(fuchsia_sysmem2::wire::SingleBufferSettings::Builder(arena_)
                                        .image_format_constraints(image_format_constraints_)
                                        .Build())
                          .Build();
    auto response =
        fuchsia_sysmem2::wire::BufferCollectionWaitForAllBuffersAllocatedResponse::Builder(arena_)
            .buffer_collection_info(collection)
            .Build();
    completer.Reply(fit::ok(&response));
  }

  void NotImplemented_(const std::string& name, fidl::CompleterBase& completer) override {
    EXPECT_TRUE(false);
  }

  void set_allocated_image_format_constraints(
      const fuchsia_sysmem2::wire::ImageFormatConstraints& image_format_constraints) {
    image_format_constraints_ = image_format_constraints;
  }
  bool set_constraints_called() const { return set_constraints_called_; }
  bool set_name_called() const { return set_name_called_; }

 private:
  fidl::Arena<fidl::kDefaultArenaInitialCapacity> arena_;
  bool set_constraints_called_ = false;
  bool set_name_called_ = false;
  fuchsia_sysmem2::wire::ImageFormatConstraints image_format_constraints_;
};

class MockBufferCollection : public MockBufferCollectionBase {
 public:
  explicit MockBufferCollection(
      const std::vector<fuchsia_images2::wire::PixelFormat>& pixel_format_types =
          {fuchsia_images2::wire::PixelFormat::kB8G8R8A8,
           fuchsia_images2::wire::PixelFormat::kR8G8B8A8})
      : supported_pixel_format_types_(pixel_format_types) {
    set_allocated_image_format_constraints(
        fuchsia_sysmem2::wire::ImageFormatConstraints::Builder(arena_)
            .pixel_format(fuchsia_images2::wire::PixelFormat::kB8G8R8A8)
            .pixel_format_modifier(fuchsia_images2::wire::PixelFormatModifier::kLinear)
            .min_size(fuchsia_math::wire::SizeU{.width = 1, .height = 4})
            .min_bytes_per_row(4096)
            .Build());
  }
  ~MockBufferCollection() override = default;

  void VerifyBufferCollectionConstraints(
      const fuchsia_sysmem2::wire::BufferCollectionConstraints& constraints) override {
    EXPECT_TRUE(constraints.buffer_memory_constraints().inaccessible_domain_supported());
    EXPECT_FALSE(constraints.buffer_memory_constraints().cpu_domain_supported());
    EXPECT_EQ(64u, constraints.image_format_constraints().at(0).bytes_per_row_divisor());

    size_t expected_format_constraints_count = 0u;
    const cpp20::span<const fuchsia_sysmem2::wire::ImageFormatConstraints> image_format_constraints(
        constraints.image_format_constraints().data(),
        constraints.image_format_constraints().count());

    const bool has_bgra =
        std::find(supported_pixel_format_types_.begin(), supported_pixel_format_types_.end(),
                  fuchsia_images2::wire::PixelFormat::kB8G8R8A8) !=
        supported_pixel_format_types_.end();
    if (has_bgra) {
      expected_format_constraints_count += 2;
      const bool image_constraints_contains_bgra32_and_linear = std::any_of(
          image_format_constraints.begin(), image_format_constraints.end(),
          [](const fuchsia_sysmem2::wire::ImageFormatConstraints& format) {
            return format.pixel_format() == fuchsia_images2::wire::PixelFormat::kB8G8R8A8 &&
                   format.pixel_format_modifier() ==
                       fuchsia_images2::wire::PixelFormatModifier::kLinear;
          });
      EXPECT_TRUE(image_constraints_contains_bgra32_and_linear);
    }

    const bool has_rgba =
        std::find(supported_pixel_format_types_.begin(), supported_pixel_format_types_.end(),
                  fuchsia_images2::wire::PixelFormat::kR8G8B8A8) !=
        supported_pixel_format_types_.end();
    if (has_rgba) {
      expected_format_constraints_count += 4;
      const bool image_constraints_contains_rgba32_and_linear = std::any_of(
          image_format_constraints.begin(), image_format_constraints.end(),
          [](const fuchsia_sysmem2::wire::ImageFormatConstraints& format) {
            return format.pixel_format() == fuchsia_images2::wire::PixelFormat::kR8G8B8A8 &&
                   format.pixel_format_modifier() ==
                       fuchsia_images2::wire::PixelFormatModifier::kLinear;
          });
      EXPECT_TRUE(image_constraints_contains_rgba32_and_linear);
      const bool image_constraints_contains_rgba32_and_afbc_16x16 = std::any_of(
          image_format_constraints.begin(), image_format_constraints.end(),
          [](const fuchsia_sysmem2::wire::ImageFormatConstraints& format) {
            return format.pixel_format() == fuchsia_images2::wire::PixelFormat::kR8G8B8A8 &&
                   format.pixel_format_modifier() ==
                       fuchsia_images2::wire::PixelFormatModifier::kArmAfbc16X16SplitBlockSparseYuv;
          });
      EXPECT_TRUE(image_constraints_contains_rgba32_and_afbc_16x16);
    }

    EXPECT_EQ(expected_format_constraints_count, constraints.image_format_constraints().count());
  }

  void VerifyName(const std::string& name) override { EXPECT_EQ(name, "Display"); }

 private:
  fidl::Arena<fidl::kDefaultArenaInitialCapacity> arena_;
  std::vector<fuchsia_images2::wire::PixelFormat> supported_pixel_format_types_;
};

class MockBufferCollectionForCapture : public MockBufferCollectionBase {
 public:
  MockBufferCollectionForCapture() {
    set_allocated_image_format_constraints(
        fuchsia_sysmem2::wire::ImageFormatConstraints::Builder(arena_)
            .pixel_format(fuchsia_images2::wire::PixelFormat::kB8G8R8)
            .pixel_format_modifier(fuchsia_images2::wire::PixelFormatModifier::kLinear)
            .min_size(fuchsia_math::wire::SizeU{.width = 1, .height = 4})
            .min_bytes_per_row(4096)
            .Build());
  }
  ~MockBufferCollectionForCapture() override = default;

  void VerifyBufferCollectionConstraints(
      const fuchsia_sysmem2::wire::BufferCollectionConstraints& constraints) override {
    EXPECT_TRUE(constraints.buffer_memory_constraints().inaccessible_domain_supported());
    EXPECT_FALSE(constraints.buffer_memory_constraints().cpu_domain_supported());
    EXPECT_EQ(64u, constraints.image_format_constraints().at(0).bytes_per_row_divisor());

    size_t expected_format_constraints_count = 1u;
    EXPECT_EQ(expected_format_constraints_count, constraints.image_format_constraints().count());

    const auto& image_format_constraints = constraints.image_format_constraints();
    EXPECT_EQ(image_format_constraints.at(0).pixel_format(),
              fuchsia_images2::wire::PixelFormat::kB8G8R8);
    EXPECT_TRUE(image_format_constraints.at(0).has_pixel_format_modifier());
    EXPECT_EQ(image_format_constraints.at(0).pixel_format_modifier(),
              fuchsia_images2::wire::PixelFormatModifier::kLinear);
  }

  void VerifyName(const std::string& name) override { EXPECT_EQ(name, "Display capture"); }

 private:
  fidl::Arena<fidl::kDefaultArenaInitialCapacity> arena_;
};

class MockAllocator : public fidl::testing::WireTestBase<fuchsia_sysmem2::Allocator> {
 public:
  using MockBufferCollectionBuilder =
      fit::function<std::unique_ptr<MockBufferCollectionBase>(void)>;

  explicit MockAllocator(async_dispatcher_t* dispatcher) : dispatcher_(dispatcher) {
    ZX_ASSERT(dispatcher_ != nullptr);
  }

  void set_mock_buffer_collection_builder(MockBufferCollectionBuilder builder) {
    mock_buffer_collection_builder_ = std::move(builder);
  }

  void BindSharedCollection(BindSharedCollectionRequestView request,
                            BindSharedCollectionCompleter::Sync& completer) override {
    ZX_ASSERT(mock_buffer_collection_builder_ != nullptr);
    auto buffer_collection_id = next_buffer_collection_id_++;
    active_buffer_collections_[buffer_collection_id] = {
        .token_client = std::move(request->token()),
        .mock_buffer_collection = mock_buffer_collection_builder_(),
    };

    fidl::BindServer(
        dispatcher_, std::move(request->buffer_collection_request()),
        active_buffer_collections_[buffer_collection_id].mock_buffer_collection.get(),
        [this, buffer_collection_id](MockBufferCollectionBase*, fidl::UnbindInfo,
                                     fidl::ServerEnd<fuchsia_sysmem2::BufferCollection>) {
          inactive_buffer_collection_tokens_.push_back(
              std::move(active_buffer_collections_[buffer_collection_id].token_client));
          active_buffer_collections_.erase(buffer_collection_id);
        });
  }

  MockBufferCollectionBase* GetMostRecentBufferCollection() {
    const display::DriverBufferCollectionId most_recent_collection_id(
        next_buffer_collection_id_.value() - 1);
    if (active_buffer_collections_.find(most_recent_collection_id) ==
        active_buffer_collections_.end()) {
      return nullptr;
    }
    return active_buffer_collections_.at(most_recent_collection_id).mock_buffer_collection.get();
  }

  std::vector<fidl::UnownedClientEnd<fuchsia_sysmem2::BufferCollectionToken>>
  GetActiveBufferCollectionTokenClients() const {
    std::vector<fidl::UnownedClientEnd<fuchsia_sysmem2::BufferCollectionToken>>
        unowned_token_clients;
    unowned_token_clients.reserve(active_buffer_collections_.size());

    for (const auto& kv : active_buffer_collections_) {
      unowned_token_clients.push_back(kv.second.token_client);
    }
    return unowned_token_clients;
  }

  std::vector<fidl::UnownedClientEnd<fuchsia_sysmem2::BufferCollectionToken>>
  GetInactiveBufferCollectionTokenClients() const {
    std::vector<fidl::UnownedClientEnd<fuchsia_sysmem2::BufferCollectionToken>>
        unowned_token_clients;
    unowned_token_clients.reserve(inactive_buffer_collection_tokens_.size());

    for (const auto& token : inactive_buffer_collection_tokens_) {
      unowned_token_clients.push_back(token);
    }
    return unowned_token_clients;
  }

  void NotImplemented_(const std::string& name, fidl::CompleterBase& completer) override {
    EXPECT_TRUE(false);
  }

 private:
  struct BufferCollection {
    fidl::ClientEnd<fuchsia_sysmem2::BufferCollectionToken> token_client;
    std::unique_ptr<MockBufferCollectionBase> mock_buffer_collection;
  };

  std::unordered_map<display::DriverBufferCollectionId, BufferCollection>
      active_buffer_collections_;
  std::vector<fidl::ClientEnd<fuchsia_sysmem2::BufferCollectionToken>>
      inactive_buffer_collection_tokens_;

  display::DriverBufferCollectionId next_buffer_collection_id_ =
      display::DriverBufferCollectionId(0);
  MockBufferCollectionBuilder mock_buffer_collection_builder_ = nullptr;

  async_dispatcher_t* dispatcher_ = nullptr;
};

class FakeCanvasProtocol : public fidl::WireServer<fuchsia_hardware_amlogiccanvas::Device> {
 public:
  explicit FakeCanvasProtocol(async_dispatcher_t* dispatcher = nullptr)
      : dispatcher_(dispatcher ? dispatcher : async_get_default_dispatcher()) {}

  void Serve(fidl::ServerEnd<fuchsia_hardware_amlogiccanvas::Device> server_end) {
    binding_.emplace(dispatcher_, std::move(server_end), this,
                     std::mem_fn(&FakeCanvasProtocol::OnFidlClosed));
  }

  void OnFidlClosed(fidl::UnbindInfo info) {}

  void Config(ConfigRequestView request, ConfigCompleter::Sync& completer) override {
    for (size_t i = 0; i < std::size(in_use_); i++) {
      ZX_DEBUG_ASSERT_MSG(i <= std::numeric_limits<uint8_t>::max(), "%zu", i);
      if (!in_use_[i]) {
        in_use_[i] = true;
        completer.ReplySuccess(static_cast<uint8_t>(i));
        return;
      }
    }
    completer.ReplyError(ZX_ERR_NO_MEMORY);
  }

  void Free(FreeRequestView request, FreeCompleter::Sync& completer) override {
    EXPECT_TRUE(in_use_[request->canvas_idx]);
    in_use_[request->canvas_idx] = false;
    completer.ReplySuccess();
  }

  void CheckThatNoEntriesInUse() {
    for (uint32_t i = 0; i < std::size(in_use_); i++) {
      EXPECT_FALSE(in_use_[i]);
    }
  }

 private:
  async_dispatcher_t* dispatcher_;
  static constexpr uint32_t kCanvasEntries = 256;
  bool in_use_[kCanvasEntries] = {};
  std::optional<fidl::ServerBinding<fuchsia_hardware_amlogiccanvas::Device>> binding_;
};

class FakeSysmemTest : public testing::Test {
 public:
  static constexpr int kWidth = 1024;
  static constexpr int kHeight = 600;

  FakeSysmemTest() : loop_(&kAsyncLoopConfigNoAttachToCurrentThread) {}

  void SetUp() override {
    mock_root_ = MockDevice::FakeRootParent();

    loop_.StartThread("sysmem-handler-loop");
    auto endpoints = fidl::Endpoints<fuchsia_hardware_amlogiccanvas::Device>::Create();
    canvas_.SyncCall(&FakeCanvasProtocol::Serve, std::move(endpoints.server));

    zx::result<std::unique_ptr<display::Namespace>> create_incoming_result =
        display::NamespaceDfv1::Create(mock_root_.get());
    ASSERT_OK(create_incoming_result.status_value());
    incoming_ = std::move(create_incoming_result).value();

    zx::result<std::unique_ptr<display::MetadataGetter>> create_metadata_getter_result =
        display::MetadataGetterDfv1::Create(mock_root_.get());
    ASSERT_OK(create_metadata_getter_result.status_value());
    metadata_getter_ = std::move(create_metadata_getter_result).value();

    zx::result<std::unique_ptr<display::DispatcherFactory>> create_dispatcher_factory_result =
        display::LoopBackedDispatcherFactory::Create(mock_root_.get());
    ASSERT_OK(create_dispatcher_factory_result.status_value());
    dispatcher_factory_ = std::move(create_dispatcher_factory_result).value();

    display_engine_ = std::make_unique<DisplayEngine>(incoming_.get(), metadata_getter_.get(),
                                                      dispatcher_factory_.get());
    display_engine_->SetFormatSupportCheck([](auto) { return true; });
    display_engine_->SetCanvasForTesting(std::move(endpoints.client));

    zx::result<std::unique_ptr<Vout>> create_dsi_vout_result = Vout::CreateDsiVoutForTesting(
        /*panel_type=*/PANEL_BOE_TV070WSM_FITIPOWER_JD9364_ASTRO, /*width=*/kWidth,
        /*height=*/kHeight);
    ASSERT_OK(create_dsi_vout_result.status_value());
    display_engine_->SetVoutForTesting(std::move(create_dsi_vout_result).value());

    PixelGridSize2D layer_image_size = {
        .width = kWidth,
        .height = kHeight,
    };
    PixelGridSize2D display_contents_size = {
        .width = kWidth,
        .height = kHeight,
    };
    zx::result<std::unique_ptr<VideoInputUnit>> video_input_unit_result =
        VideoInputUnit::CreateForTesting(vpu_mmio_.GetMmioBuffer(), /*rdma=*/nullptr,
                                         layer_image_size, display_contents_size);
    ASSERT_OK(video_input_unit_result.status_value());
    display_engine_->SetVideoInputUnitForTesting(std::move(video_input_unit_result).value());

    allocator_ = std::make_unique<MockAllocator>(loop_.dispatcher());
    allocator_->set_mock_buffer_collection_builder([] {
      // Allocate importable primary Image by default.
      const std::vector<fuchsia_images2::wire::PixelFormat> kPixelFormats = {
          fuchsia_images2::wire::PixelFormat::kB8G8R8A8,
          fuchsia_images2::wire::PixelFormat::kR8G8B8A8};
      return std::make_unique<MockBufferCollection>(kPixelFormats);
    });

    {
      auto endpoints = fidl::Endpoints<fuchsia_sysmem2::Allocator>::Create();
      fidl::BindServer(loop_.dispatcher(), std::move(endpoints.server), allocator_.get());
      display_engine_->SetSysmemAllocatorForTesting(
          fidl::WireSyncClient(std::move(endpoints.client)));
    }
  }

  void TearDown() override {
    // Shutdown the loop before destroying the MockAllocator which may still have
    // pending callbacks.
    loop_.Shutdown();
    loop_.JoinThreads();
  }

 protected:
  std::shared_ptr<MockDevice> mock_root_;
  async::Loop loop_;

  std::unique_ptr<display::Namespace> incoming_;
  std::unique_ptr<display::MetadataGetter> metadata_getter_;
  std::unique_ptr<display::DispatcherFactory> dispatcher_factory_;

  ddk_fake::FakeMmioRegRegion vpu_mmio_ =
      ddk_fake::FakeMmioRegRegion(/*reg_size=*/4, /*reg_count=*/0x10000);
  std::unique_ptr<DisplayEngine> display_engine_;
  std::unique_ptr<MockAllocator> allocator_;
  async_patterns::TestDispatcherBound<FakeCanvasProtocol> canvas_{loop_.dispatcher(),
                                                                  std::in_place};
};

template <typename Lambda>
bool PollUntil(Lambda predicate, zx::duration poll_interval, int max_intervals) {
  ZX_ASSERT(max_intervals >= 0);

  for (int sleeps_left = max_intervals; sleeps_left > 0; --sleeps_left) {
    if (predicate())
      return true;
    zx::nanosleep(zx::deadline_after(poll_interval));
  }

  return predicate();
}

TEST_F(FakeSysmemTest, ImportBufferCollection) {
  zx::result<fidl::Endpoints<fuchsia_sysmem2::BufferCollectionToken>> token1_endpoints =
      fidl::CreateEndpoints<fuchsia_sysmem2::BufferCollectionToken>();
  ASSERT_OK(token1_endpoints.status_value());
  zx::result<fidl::Endpoints<fuchsia_sysmem2::BufferCollectionToken>> token2_endpoints =
      fidl::CreateEndpoints<fuchsia_sysmem2::BufferCollectionToken>();
  ASSERT_OK(token2_endpoints.status_value());

  // Test ImportBufferCollection().
  constexpr display::DriverBufferCollectionId kValidBufferCollectionId(1);
  constexpr uint64_t kBanjoValidBufferCollectionId =
      display::ToBanjoDriverBufferCollectionId(kValidBufferCollectionId);
  EXPECT_OK(display_engine_->DisplayControllerImplImportBufferCollection(
      kBanjoValidBufferCollectionId, token1_endpoints->client.TakeChannel()));

  // `driver_buffer_collection_id` must be unused.
  EXPECT_EQ(display_engine_->DisplayControllerImplImportBufferCollection(
                kBanjoValidBufferCollectionId, token2_endpoints->client.TakeChannel()),
            ZX_ERR_ALREADY_EXISTS);

  EXPECT_TRUE(
      PollUntil([&]() { return !allocator_->GetActiveBufferCollectionTokenClients().empty(); },
                zx::msec(5), 1000));

  // Verify that the current buffer collection token is used (active).
  {
    auto active_buffer_token_clients = allocator_->GetActiveBufferCollectionTokenClients();
    EXPECT_EQ(active_buffer_token_clients.size(), 1u);

    auto inactive_buffer_token_clients = allocator_->GetInactiveBufferCollectionTokenClients();
    EXPECT_EQ(inactive_buffer_token_clients.size(), 0u);

    auto [client_koid, client_related_koid] =
        fsl::GetKoids(active_buffer_token_clients[0].channel()->get());
    auto [server_koid, server_related_koid] =
        fsl::GetKoids(token1_endpoints->server.channel().get());

    EXPECT_NE(client_koid, ZX_KOID_INVALID);
    EXPECT_NE(client_related_koid, ZX_KOID_INVALID);
    EXPECT_NE(server_koid, ZX_KOID_INVALID);
    EXPECT_NE(server_related_koid, ZX_KOID_INVALID);

    EXPECT_EQ(client_koid, server_related_koid);
    EXPECT_EQ(server_koid, client_related_koid);
  }

  // Test ReleaseBufferCollection().
  constexpr display::DriverBufferCollectionId kInvalidBufferCollectionId(2);
  constexpr uint64_t kBanjoInvalidBufferCollectionId =
      display::ToBanjoDriverBufferCollectionId(kInvalidBufferCollectionId);
  EXPECT_EQ(display_engine_->DisplayControllerImplReleaseBufferCollection(
                kBanjoInvalidBufferCollectionId),
            ZX_ERR_NOT_FOUND);
  EXPECT_OK(
      display_engine_->DisplayControllerImplReleaseBufferCollection(kBanjoValidBufferCollectionId));

  EXPECT_TRUE(
      PollUntil([&]() { return allocator_->GetActiveBufferCollectionTokenClients().empty(); },
                zx::msec(5), 1000));

  // Verify that the current buffer collection token is released (inactive).
  {
    auto active_buffer_token_clients = allocator_->GetActiveBufferCollectionTokenClients();
    EXPECT_EQ(active_buffer_token_clients.size(), 0u);

    auto inactive_buffer_token_clients = allocator_->GetInactiveBufferCollectionTokenClients();
    EXPECT_EQ(inactive_buffer_token_clients.size(), 1u);

    auto [client_koid, client_related_koid] =
        fsl::GetKoids(inactive_buffer_token_clients[0].channel()->get());
    auto [server_koid, server_related_koid] =
        fsl::GetKoids(token1_endpoints->server.channel().get());

    EXPECT_NE(client_koid, ZX_KOID_INVALID);
    EXPECT_NE(client_related_koid, ZX_KOID_INVALID);
    EXPECT_NE(server_koid, ZX_KOID_INVALID);
    EXPECT_NE(server_related_koid, ZX_KOID_INVALID);

    EXPECT_EQ(client_koid, server_related_koid);
    EXPECT_EQ(server_koid, client_related_koid);
  }
}

TEST_F(FakeSysmemTest, ImportImage) {
  auto [token_client, token_server] =
      fidl::Endpoints<fuchsia_sysmem2::BufferCollectionToken>::Create();

  constexpr display::DriverBufferCollectionId kBufferCollectionId(1);
  constexpr uint64_t kBanjoBufferCollectionId =
      display::ToBanjoDriverBufferCollectionId(kBufferCollectionId);
  EXPECT_OK(display_engine_->DisplayControllerImplImportBufferCollection(
      kBanjoBufferCollectionId, token_client.TakeChannel()));

  static constexpr image_buffer_usage_t kDisplayUsage = {
      .tiling_type = IMAGE_TILING_TYPE_LINEAR,
  };
  EXPECT_OK(display_engine_->DisplayControllerImplSetBufferCollectionConstraints(
      &kDisplayUsage, kBanjoBufferCollectionId));

  constexpr display::DriverBufferCollectionId kInvalidBufferCollectionId(100);
  constexpr uint64_t kBanjoInvalidBufferCollectionId =
      display::ToBanjoDriverBufferCollectionId(kInvalidBufferCollectionId);
  EXPECT_EQ(display_engine_->DisplayControllerImplSetBufferCollectionConstraints(
                &kDisplayUsage, kBanjoInvalidBufferCollectionId),
            ZX_ERR_NOT_FOUND);

  // Invalid import: Bad image type.
  static constexpr image_metadata_t kInvalidTilingMetadata = {
      .width = 1024,
      .height = 768,
      .tiling_type = IMAGE_TILING_TYPE_CAPTURE,
  };
  uint64_t image_handle = 0;
  EXPECT_EQ(display_engine_->DisplayControllerImplImportImage(&kInvalidTilingMetadata,
                                                              kBanjoBufferCollectionId,
                                                              /*index=*/0, &image_handle),
            ZX_ERR_INVALID_ARGS);

  // Invalid import: Invalid collection ID.
  static constexpr image_metadata_t kDisplayImageMetadata = {
      .width = 1024,
      .height = 768,
      .tiling_type = IMAGE_TILING_TYPE_LINEAR,
  };
  EXPECT_EQ(display_engine_->DisplayControllerImplImportImage(&kDisplayImageMetadata,
                                                              kBanjoInvalidBufferCollectionId,
                                                              /*index=*/0, &image_handle),
            ZX_ERR_NOT_FOUND);

  // Invalid import: Invalid buffer collection index.
  constexpr uint64_t kInvalidBufferCollectionIndex = 100u;
  image_handle = 0;
  EXPECT_EQ(display_engine_->DisplayControllerImplImportImage(
                &kDisplayImageMetadata, kBanjoBufferCollectionId, kInvalidBufferCollectionIndex,
                &image_handle),
            ZX_ERR_OUT_OF_RANGE);

  // Valid import.
  EXPECT_OK(display_engine_->DisplayControllerImplImportImage(&kDisplayImageMetadata,
                                                              kBanjoBufferCollectionId,
                                                              /*index=*/0, &image_handle));
  EXPECT_NE(image_handle, 0u);

  // Release the image.
  display_engine_->DisplayControllerImplReleaseImage(image_handle);

  EXPECT_OK(
      display_engine_->DisplayControllerImplReleaseBufferCollection(kBanjoBufferCollectionId));
}

TEST_F(FakeSysmemTest, ImportImageForCapture) {
  allocator_->set_mock_buffer_collection_builder(
      [] { return std::make_unique<MockBufferCollectionForCapture>(); });

  auto [token_client, token_server] =
      fidl::Endpoints<fuchsia_sysmem2::BufferCollectionToken>::Create();

  constexpr display::DriverBufferCollectionId kBufferCollectionId(1);
  constexpr uint64_t kBanjoBufferCollectionId =
      display::ToBanjoDriverBufferCollectionId(kBufferCollectionId);
  EXPECT_OK(display_engine_->DisplayControllerImplImportBufferCollection(
      kBanjoBufferCollectionId, token_client.TakeChannel()));

  // Driver sets BufferCollection buffer memory constraints.
  static constexpr image_buffer_usage_t kCaptureUsage = {
      .tiling_type = IMAGE_TILING_TYPE_CAPTURE,
  };
  EXPECT_OK(display_engine_->DisplayControllerImplSetBufferCollectionConstraints(
      &kCaptureUsage, kBanjoBufferCollectionId));

  // Invalid import: invalid buffer collection ID.
  uint64_t capture_handle = 0;
  const uint64_t kBanjoInvalidBufferCollectionId = 100;
  EXPECT_EQ(
      display_engine_->DisplayControllerImplImportImageForCapture(kBanjoInvalidBufferCollectionId,
                                                                  /*index=*/0, &capture_handle),
      ZX_ERR_NOT_FOUND);

  // Invalid import: index out of range.
  const uint64_t kInvalidIndex = 100;
  EXPECT_EQ(display_engine_->DisplayControllerImplImportImageForCapture(
                kBanjoBufferCollectionId, kInvalidIndex, &capture_handle),
            ZX_ERR_OUT_OF_RANGE);

  // Valid import.
  capture_handle = 0;
  EXPECT_OK(display_engine_->DisplayControllerImplImportImageForCapture(kBanjoBufferCollectionId,
                                                                        /*index=*/0,
                                                                        &capture_handle));
  EXPECT_NE(capture_handle, 0u);

  // Release the image.
  display_engine_->DisplayControllerImplReleaseCapture(capture_handle);

  EXPECT_OK(
      display_engine_->DisplayControllerImplReleaseBufferCollection(kBanjoBufferCollectionId));
}

TEST_F(FakeSysmemTest, SysmemRequirements) {
  MockBufferCollectionBase* collection = nullptr;
  allocator_->set_mock_buffer_collection_builder([&collection] {
    const std::vector<fuchsia_images2::wire::PixelFormat> kPixelFormats = {
        fuchsia_images2::wire::PixelFormat::kB8G8R8A8,
        fuchsia_images2::wire::PixelFormat::kR8G8B8A8};
    auto new_buffer_collection = std::make_unique<MockBufferCollection>(kPixelFormats);
    collection = new_buffer_collection.get();
    return new_buffer_collection;
  });

  auto [token_client, token_server] =
      fidl::Endpoints<fuchsia_sysmem2::BufferCollectionToken>::Create();

  constexpr display::DriverBufferCollectionId kBufferCollectionId(1);
  constexpr uint64_t kBanjoBufferCollectionId =
      display::ToBanjoDriverBufferCollectionId(kBufferCollectionId);
  EXPECT_OK(display_engine_->DisplayControllerImplImportBufferCollection(
      kBanjoBufferCollectionId, token_client.TakeChannel()));

  EXPECT_TRUE(PollUntil([&] { return collection != nullptr; }, zx::msec(5), 1000));

  static constexpr image_buffer_usage_t kDisplayUsage = {
      .tiling_type = IMAGE_TILING_TYPE_LINEAR,
  };
  EXPECT_OK(display_engine_->DisplayControllerImplSetBufferCollectionConstraints(
      &kDisplayUsage, kBanjoBufferCollectionId));

  EXPECT_TRUE(PollUntil([&] { return collection->set_constraints_called(); }, zx::msec(5), 1000));
  EXPECT_TRUE(collection->set_name_called());
}

TEST_F(FakeSysmemTest, SysmemRequirements_BgraOnly) {
  MockBufferCollectionBase* collection = nullptr;
  allocator_->set_mock_buffer_collection_builder([&collection] {
    const std::vector<fuchsia_images2::wire::PixelFormat> kPixelFormats = {
        fuchsia_images2::wire::PixelFormat::kB8G8R8A8,
    };
    auto new_buffer_collection = std::make_unique<MockBufferCollection>(kPixelFormats);
    collection = new_buffer_collection.get();
    return new_buffer_collection;
  });
  display_engine_->SetFormatSupportCheck([](fuchsia_images2::wire::PixelFormat format) {
    return format == fuchsia_images2::wire::PixelFormat::kB8G8R8A8;
  });

  auto [token_client, token_server] =
      fidl::Endpoints<fuchsia_sysmem2::BufferCollectionToken>::Create();

  constexpr display::DriverBufferCollectionId kBufferCollectionId(1);
  constexpr uint64_t kBanjoBufferCollectionId =
      display::ToBanjoDriverBufferCollectionId(kBufferCollectionId);
  EXPECT_OK(display_engine_->DisplayControllerImplImportBufferCollection(
      kBanjoBufferCollectionId, token_client.TakeChannel()));

  EXPECT_TRUE(PollUntil([&] { return collection != nullptr; }, zx::msec(5), 1000));

  static constexpr image_buffer_usage_t kDisplayUsage = {
      .tiling_type = IMAGE_TILING_TYPE_LINEAR,
  };
  EXPECT_OK(display_engine_->DisplayControllerImplSetBufferCollectionConstraints(
      &kDisplayUsage, kBanjoBufferCollectionId));

  EXPECT_TRUE(PollUntil([&] { return collection->set_constraints_called(); }, zx::msec(5), 1000));
  EXPECT_TRUE(collection->set_name_called());
}

TEST(AmlogicDisplay, FloatToFix3_10) {
  inspect::Inspector inspector;
  EXPECT_EQ(0x0000u, VideoInputUnit::FloatToFixed3_10(0.0f));
  EXPECT_EQ(0x0066u, VideoInputUnit::FloatToFixed3_10(0.1f));
  EXPECT_EQ(0x1f9au, VideoInputUnit::FloatToFixed3_10(-0.1f));
  // Test for maximum positive (<4)
  EXPECT_EQ(0x0FFFu, VideoInputUnit::FloatToFixed3_10(4.0f));
  EXPECT_EQ(0x0FFFu, VideoInputUnit::FloatToFixed3_10(40.0f));
  EXPECT_EQ(0x0FFFu, VideoInputUnit::FloatToFixed3_10(3.9999f));
  // Test for minimum negative (>= -4)
  EXPECT_EQ(0x1000u, VideoInputUnit::FloatToFixed3_10(-4.0f));
  EXPECT_EQ(0x1000u, VideoInputUnit::FloatToFixed3_10(-14.0f));
}

TEST(AmlogicDisplay, FloatToFixed2_10) {
  inspect::Inspector inspector;
  EXPECT_EQ(0x0000u, VideoInputUnit::FloatToFixed2_10(0.0f));
  EXPECT_EQ(0x0066u, VideoInputUnit::FloatToFixed2_10(0.1f));
  EXPECT_EQ(0x0f9au, VideoInputUnit::FloatToFixed2_10(-0.1f));
  // Test for maximum positive (<2)
  EXPECT_EQ(0x07FFu, VideoInputUnit::FloatToFixed2_10(2.0f));
  EXPECT_EQ(0x07FFu, VideoInputUnit::FloatToFixed2_10(20.0f));
  EXPECT_EQ(0x07FFu, VideoInputUnit::FloatToFixed2_10(1.9999f));
  // Test for minimum negative (>= -2)
  EXPECT_EQ(0x0800u, VideoInputUnit::FloatToFixed2_10(-2.0f));
  EXPECT_EQ(0x0800u, VideoInputUnit::FloatToFixed2_10(-14.0f));
}

TEST_F(FakeSysmemTest, NoLeakCaptureCanvas) {
  allocator_->set_mock_buffer_collection_builder(
      [] { return std::make_unique<MockBufferCollectionForCapture>(); });

  auto [token_client, token_server] =
      fidl::Endpoints<fuchsia_sysmem2::BufferCollectionToken>::Create();

  constexpr display::DriverBufferCollectionId kBufferCollectionId(1);
  constexpr uint64_t kBanjoBufferCollectionId =
      display::ToBanjoDriverBufferCollectionId(kBufferCollectionId);
  EXPECT_OK(display_engine_->DisplayControllerImplImportBufferCollection(
      kBanjoBufferCollectionId, token_client.TakeChannel()));

  uint64_t capture_handle;
  EXPECT_OK(display_engine_->DisplayControllerImplImportImageForCapture(kBanjoBufferCollectionId,
                                                                        /*index=*/0,
                                                                        &capture_handle));
  EXPECT_OK(display_engine_->DisplayControllerImplReleaseCapture(capture_handle));

  canvas_.SyncCall(&FakeCanvasProtocol::CheckThatNoEntriesInUse);
}

}  // namespace

}  // namespace amlogic_display
