// Copyright 2020 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/ui/scenic/lib/flatland/buffers/buffer_collection.h"

#include <lib/fdio/directory.h>

#include <gtest/gtest.h>

#include "src/lib/fsl/handles/object_info.h"
#include "src/ui/scenic/lib/flatland/buffers/util.h"

namespace flatland {
namespace test {

// Common testing base class to be used across different unittests that
// require Vulkan and a SysmemAllocator.
class BufferCollectionTest : public ::testing::Test {
 protected:
  void SetUp() override {
    ::testing::Test::SetUp();
    // Create the SysmemAllocator.
    zx_status_t status = fdio_service_connect(
        "/svc/fuchsia.sysmem.Allocator", sysmem_allocator_.NewRequest().TakeChannel().release());
    EXPECT_EQ(status, ZX_OK);
    sysmem_allocator_->SetDebugClientInfo(fsl::GetCurrentProcessName(),
                                          fsl::GetCurrentProcessKoid());
  }

  void TearDown() override {
    sysmem_allocator_ = nullptr;
    ::testing::Test::TearDown();
  }

  fuchsia::sysmem::AllocatorSyncPtr sysmem_allocator_;
};

// Test the creation of a buffer collection that doesn't have any additional vulkan
// constraints to show that it doesn't need vulkan to be valid.
TEST_F(BufferCollectionTest, CreateCollectionTest) {
  auto tokens = SysmemTokens::Create(sysmem_allocator_.get());
  auto result = BufferCollectionInfo::New(sysmem_allocator_.get(), std::move(tokens.dup_token));
  EXPECT_TRUE(result.is_ok());
}

// This test ensures that the buffer collection can still be allocated even if the server
// does not set extra customizable constraints via a call to GenerateToken(). This is
// necessary due to the fact that the buffer collection keeps around a dummy token in
// case new constraints need to be added, but the existence of the dummy token itself
// prevents allocation until it is closed out. So this test makes sure that when we close
// out the dummy token inside the call to WaitUntilAllocated() that this is enough to ensure
// that we can still allocate the buffer collection.
TEST_F(BufferCollectionTest, AllocationWithoutExtraConstraints) {
  auto tokens = SysmemTokens::Create(sysmem_allocator_.get());
  auto result = BufferCollectionInfo::New(sysmem_allocator_.get(), std::move(tokens.dup_token));
  EXPECT_TRUE(result.is_ok());

  auto collection = std::move(result.value());

  // Client hasn't set their constraints yet, so this should be false.
  EXPECT_FALSE(collection.BuffersAreAllocated());

  {
    const uint32_t kWidth = 32;
    const uint32_t kHeight = 64;
    fuchsia::sysmem::BufferCollectionSyncPtr buffer_collection;
    zx_status_t status = sysmem_allocator_->BindSharedCollection(std::move(tokens.local_token),
                                                                 buffer_collection.NewRequest());
    buffer_collection->SetName(100u, "FlatlandAllocationWithoutExtraConstraints");
    EXPECT_EQ(status, ZX_OK);
    fuchsia::sysmem::BufferCollectionConstraints constraints;
    constraints.has_buffer_memory_constraints = true;
    constraints.buffer_memory_constraints.cpu_domain_supported = true;
    constraints.buffer_memory_constraints.ram_domain_supported = true;
    constraints.usage.cpu = fuchsia::sysmem::cpuUsageWriteOften;
    constraints.min_buffer_count = 1;

    constraints.image_format_constraints_count = 1;
    auto& image_constraints = constraints.image_format_constraints[0];
    image_constraints.color_spaces_count = 1;
    image_constraints.color_space[0] =
        fuchsia::sysmem::ColorSpace{.type = fuchsia::sysmem::ColorSpaceType::SRGB};
    image_constraints.pixel_format.type = fuchsia::sysmem::PixelFormatType::BGRA32;
    image_constraints.pixel_format.has_format_modifier = true;
    image_constraints.pixel_format.format_modifier.value = fuchsia::sysmem::FORMAT_MODIFIER_LINEAR;

    image_constraints.required_min_coded_width = kWidth;
    image_constraints.required_min_coded_height = kHeight;
    image_constraints.required_max_coded_width = kWidth;
    image_constraints.required_max_coded_height = kHeight;
    image_constraints.max_coded_width = kWidth * 4;
    image_constraints.max_coded_height = kHeight;
    image_constraints.max_bytes_per_row = 0xffffffff;

    status = buffer_collection->SetConstraints(true, constraints);
    EXPECT_EQ(status, ZX_OK);

    // Have the client wait for allocation.
    zx_status_t allocation_status = ZX_OK;
    fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info = {};
    status =
        buffer_collection->WaitForBuffersAllocated(&allocation_status, &buffer_collection_info);
    EXPECT_EQ(status, ZX_OK);
    EXPECT_EQ(allocation_status, ZX_OK);

    status = buffer_collection->Close();
    EXPECT_EQ(status, ZX_OK);
  }

  // Checking allocation on the server should return true.
  EXPECT_TRUE(collection.BuffersAreAllocated());
}

// Check to make sure |CreateBufferCollectionAndSetConstraints| returns false if
// an invalid BufferCollectionHandle is provided by the user.
TEST_F(BufferCollectionTest, NullTokenTest) {
  auto result = BufferCollectionInfo::New(sysmem_allocator_.get(),
                                          /*token*/ nullptr);
  EXPECT_TRUE(result.is_error());
}

// We pass in a valid channel to |CreateBufferCollectionAndSetConstraints|, but
// it's not actually a channel to a BufferCollection.
TEST_F(BufferCollectionTest, WrongTokenTypeTest) {
  zx::channel local_endpoint;
  zx::channel remote_endpoint;
  zx::channel::create(0, &local_endpoint, &remote_endpoint);

  // Here we inject a generic channel into a BufferCollectionHandle before passing the
  // handle into |CreateCollectionAndSetConstraints|. So the channel is valid,
  // but it is just not a BufferCollectionToken.
  BufferCollectionHandle handle{std::move(remote_endpoint)};

  // Make sure the handle is valid before passing it in.
  ASSERT_TRUE(handle.is_valid());

  // We should not be able to make a BufferCollectionInfon object with the wrong token type
  // passed in as a parameter.
  auto result = BufferCollectionInfo::New(sysmem_allocator_.get(), std::move(handle));
  EXPECT_TRUE(result.is_error());
}

// If the client sets constraints on the buffer collection that are incompatible
// with the constraints set on the server-side by the renderer, then waiting on
// the buffers to be allocated should fail.
TEST_F(BufferCollectionTest, IncompatibleConstraintsTest) {
  auto tokens = SysmemTokens::Create(sysmem_allocator_.get());
  auto result = BufferCollectionInfo::New(sysmem_allocator_.get(), std::move(tokens.dup_token));
  EXPECT_TRUE(result.is_ok());

  auto collection = std::move(result.value());

  // Create a client-side handle to the buffer collection and set the client
  // constraints. We set it to have a max of zero buffers and to not use
  // vulkan sampling, which the server side will specify is necessary.
  {
    fuchsia::sysmem::BufferCollectionSyncPtr client_collection;
    zx_status_t status = sysmem_allocator_->BindSharedCollection(std::move(tokens.local_token),
                                                                 client_collection.NewRequest());
    EXPECT_EQ(status, ZX_OK);
    client_collection->SetName(100u, "FlatlandIncompatibleConstraintsTest");
    fuchsia::sysmem::BufferCollectionConstraints constraints;
    constraints.has_buffer_memory_constraints = true;
    constraints.buffer_memory_constraints.cpu_domain_supported = true;
    constraints.buffer_memory_constraints.ram_domain_supported = true;
    constraints.usage.cpu = fuchsia::sysmem::cpuUsageWriteOften;

    // Need at least one buffer normally.
    constraints.min_buffer_count = 0;
    constraints.max_buffer_count = 0;

    constraints.usage.vulkan = !fuchsia::sysmem::vulkanUsageSampled;

    constraints.image_format_constraints_count = 1;
    auto& image_constraints = constraints.image_format_constraints[0];
    image_constraints.color_spaces_count = 0;

    image_constraints.pixel_format.type = fuchsia::sysmem::PixelFormatType::R8G8B8A8;
    image_constraints.pixel_format.has_format_modifier = true;
    image_constraints.pixel_format.format_modifier.value = fuchsia::sysmem::FORMAT_MODIFIER_LINEAR;

    // The renderer requires that the the buffer can at least have a
    // width/height of 1, which is not possible here.
    image_constraints.required_min_coded_width = 0;
    image_constraints.required_min_coded_height = 0;
    image_constraints.required_max_coded_width = 0;
    image_constraints.required_max_coded_height = 0;
    image_constraints.max_coded_width = 0;
    image_constraints.max_coded_height = 0;
    image_constraints.max_bytes_per_row = 0x0;
    status = client_collection->SetConstraints(true, constraints);
    EXPECT_EQ(status, ZX_OK);

    // Have the client wait for allocation.
    zx_status_t allocation_status = ZX_OK;
    fuchsia::sysmem::BufferCollectionInfo_2 buffer_collection_info = {};
    status =
        client_collection->WaitForBuffersAllocated(&allocation_status, &buffer_collection_info);

    // Sysmem reports the error here through |status|.
    EXPECT_NE(status, ZX_OK);
    EXPECT_EQ(allocation_status, ZX_OK);
  }

  // This should fail as sysmem won't be able to allocate anything.
  EXPECT_FALSE(collection.BuffersAreAllocated());
}

}  // namespace test
}  // namespace flatland
