// Copyright 2013 The Flutter 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 "flutter/fml/synchronization/waitable_event.h"
#include "flutter/testing/testing.h"  // IWYU pragma: keep
#include "impeller/base/validation.h"
#include "impeller/core/formats.h"
#include "impeller/renderer/backend/vulkan/command_pool_vk.h"
#include "impeller/renderer/backend/vulkan/context_vk.h"
#include "impeller/renderer/backend/vulkan/test/mock_vulkan.h"

namespace impeller {
namespace testing {

TEST(ContextVKTest, CommonHardwareConcurrencyConfigurations) {
  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(100u), 4u);
  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(9u), 4u);
  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(8u), 4u);
  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(7u), 3u);
  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(6u), 3u);
  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(5u), 2u);
  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(4u), 2u);
  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(3u), 1u);
  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(2u), 1u);
  EXPECT_EQ(ContextVK::ChooseThreadCountForWorkers(1u), 1u);
}

TEST(ContextVKTest, DeletesCommandPools) {
  std::weak_ptr<ContextVK> weak_context;
  std::weak_ptr<CommandPoolVK> weak_pool;
  {
    std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
    auto const pool = context->GetCommandPoolRecycler()->Get();
    weak_pool = pool;
    weak_context = context;
    ASSERT_TRUE(weak_pool.lock());
    ASSERT_TRUE(weak_context.lock());
  }
  ASSERT_FALSE(weak_pool.lock());
  ASSERT_FALSE(weak_context.lock());
}

TEST(ContextVKTest, DeletesCommandPoolsOnAllThreads) {
  std::weak_ptr<ContextVK> weak_context;
  std::weak_ptr<CommandPoolVK> weak_pool_main;

  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
  weak_pool_main = context->GetCommandPoolRecycler()->Get();
  weak_context = context;
  ASSERT_TRUE(weak_pool_main.lock());
  ASSERT_TRUE(weak_context.lock());

  // Start a second thread that obtains a command pool.
  fml::AutoResetWaitableEvent latch1, latch2;
  std::weak_ptr<CommandPoolVK> weak_pool_thread;
  std::thread thread([&]() {
    weak_pool_thread = context->GetCommandPoolRecycler()->Get();
    latch1.Signal();
    latch2.Wait();
  });

  // Delete the ContextVK on the main thread.
  latch1.Wait();
  context.reset();
  ASSERT_FALSE(weak_pool_main.lock());
  ASSERT_FALSE(weak_context.lock());

  // Stop the second thread and check that its command pool has been deleted.
  latch2.Signal();
  thread.join();
  ASSERT_FALSE(weak_pool_thread.lock());
}

TEST(ContextVKTest, DeletePipelineAfterContext) {
  std::shared_ptr<Pipeline<PipelineDescriptor>> pipeline;
  std::shared_ptr<std::vector<std::string>> functions;
  {
    std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
    PipelineDescriptor pipeline_desc;
    pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
    PipelineFuture<PipelineDescriptor> pipeline_future =
        context->GetPipelineLibrary()->GetPipeline(pipeline_desc);
    pipeline = pipeline_future.Get();
    ASSERT_TRUE(pipeline);
    functions = GetMockVulkanFunctions(context->GetDevice());
    ASSERT_TRUE(std::find(functions->begin(), functions->end(),
                          "vkCreateGraphicsPipelines") != functions->end());
  }
  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
                        "vkDestroyDevice") != functions->end());
}

TEST(ContextVKTest, DeleteShaderFunctionAfterContext) {
  std::shared_ptr<const ShaderFunction> shader_function;
  std::shared_ptr<std::vector<std::string>> functions;
  {
    std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
    PipelineDescriptor pipeline_desc;
    pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
    std::vector<uint8_t> data = {0x03, 0x02, 0x23, 0x07};
    context->GetShaderLibrary()->RegisterFunction(
        "foobar_fragment_main", ShaderStage::kFragment,
        std::make_shared<fml::DataMapping>(data), [](bool) {});
    shader_function = context->GetShaderLibrary()->GetFunction(
        "foobar_fragment_main", ShaderStage::kFragment);
    ASSERT_TRUE(shader_function);
    functions = GetMockVulkanFunctions(context->GetDevice());
    ASSERT_TRUE(std::find(functions->begin(), functions->end(),
                          "vkCreateShaderModule") != functions->end());
  }
  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
                        "vkDestroyDevice") != functions->end());
}

TEST(ContextVKTest, DeletePipelineLibraryAfterContext) {
  std::shared_ptr<PipelineLibrary> pipeline_library;
  std::shared_ptr<std::vector<std::string>> functions;
  {
    std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();
    PipelineDescriptor pipeline_desc;
    pipeline_desc.SetVertexDescriptor(std::make_shared<VertexDescriptor>());
    pipeline_library = context->GetPipelineLibrary();
    functions = GetMockVulkanFunctions(context->GetDevice());
    ASSERT_TRUE(std::find(functions->begin(), functions->end(),
                          "vkCreatePipelineCache") != functions->end());
  }
  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
                        "vkDestroyDevice") != functions->end());
}

TEST(ContextVKTest, CanCreateContextInAbsenceOfValidationLayers) {
  // The mocked methods don't report the presence of a validation layer but we
  // explicitly ask for validation. Context creation should continue anyway.
  auto context = MockVulkanContextBuilder()
                     .SetSettingsCallback([](auto& settings) {
                       settings.enable_validation = true;
                     })
                     .Build();
  ASSERT_NE(context, nullptr);
  const CapabilitiesVK* capabilites_vk =
      reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
  ASSERT_FALSE(capabilites_vk->AreValidationsEnabled());
}

TEST(ContextVKTest, CanCreateContextWithValidationLayers) {
  auto context =
      MockVulkanContextBuilder()
          .SetSettingsCallback(
              [](auto& settings) { settings.enable_validation = true; })
          .SetInstanceExtensions(
              {"VK_KHR_surface", "VK_MVK_macos_surface", "VK_EXT_debug_utils"})
          .SetInstanceLayers({"VK_LAYER_KHRONOS_validation"})
          .Build();
  ASSERT_NE(context, nullptr);
  const CapabilitiesVK* capabilites_vk =
      reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
  ASSERT_TRUE(capabilites_vk->AreValidationsEnabled());
}

// In Impeller's 2D renderer, we no longer use stencil-only formats. They're
// less widely supported than combined depth-stencil formats, so make sure we
// don't fail initialization if we can't find a suitable stencil format.
TEST(CapabilitiesVKTest, ContextInitializesWithNoStencilFormat) {
  const std::shared_ptr<ContextVK> context =
      MockVulkanContextBuilder()
          .SetPhysicalDeviceFormatPropertiesCallback(
              [](VkPhysicalDevice physicalDevice, VkFormat format,
                 VkFormatProperties* pFormatProperties) {
                if (format == VK_FORMAT_R8G8B8A8_UNORM) {
                  pFormatProperties->optimalTilingFeatures =
                      static_cast<VkFormatFeatureFlags>(
                          vk::FormatFeatureFlagBits::eColorAttachment);
                } else if (format == VK_FORMAT_D32_SFLOAT_S8_UINT) {
                  pFormatProperties->optimalTilingFeatures =
                      static_cast<VkFormatFeatureFlags>(
                          vk::FormatFeatureFlagBits::eDepthStencilAttachment);
                }
                // Ignore just the stencil format.
              })
          .Build();
  ASSERT_NE(context, nullptr);
  const CapabilitiesVK* capabilites_vk =
      reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
  ASSERT_EQ(capabilites_vk->GetDefaultDepthStencilFormat(),
            PixelFormat::kD32FloatS8UInt);
  ASSERT_EQ(capabilites_vk->GetDefaultStencilFormat(),
            PixelFormat::kD32FloatS8UInt);
}

// Impeller's 2D renderer relies on hardware support for a combined
// depth-stencil format (widely supported). So fail initialization if a suitable
// one couldn't be found. That way we have an opportunity to fallback to
// OpenGLES.
TEST(CapabilitiesVKTest,
     ContextFailsInitializationForNoCombinedDepthStencilFormat) {
  ScopedValidationDisable disable_validation;
  const std::shared_ptr<ContextVK> context =
      MockVulkanContextBuilder()
          .SetPhysicalDeviceFormatPropertiesCallback(
              [](VkPhysicalDevice physicalDevice, VkFormat format,
                 VkFormatProperties* pFormatProperties) {
                if (format == VK_FORMAT_R8G8B8A8_UNORM) {
                  pFormatProperties->optimalTilingFeatures =
                      static_cast<VkFormatFeatureFlags>(
                          vk::FormatFeatureFlagBits::eColorAttachment);
                }
                // Ignore combined depth-stencil formats.
              })
          .Build();
  ASSERT_EQ(context, nullptr);
}

TEST(ContextVKTest, WarmUpFunctionCreatesRenderPass) {
  const std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();

  context->SetOffscreenFormat(PixelFormat::kR8G8B8A8UNormInt);
  context->InitializeCommonlyUsedShadersIfNeeded();

  auto functions = GetMockVulkanFunctions(context->GetDevice());
  ASSERT_TRUE(std::find(functions->begin(), functions->end(),
                        "vkCreateRenderPass") != functions->end());
}

TEST(ContextVKTest, FatalMissingValidations) {
  EXPECT_DEATH(const std::shared_ptr<ContextVK> context =
                   MockVulkanContextBuilder()
                       .SetSettingsCallback([](ContextVK::Settings& settings) {
                         settings.enable_validation = true;
                         settings.fatal_missing_validations = true;
                       })
                       .Build(),
               "");
}

TEST(ContextVKTest, HasDefaultColorFormat) {
  std::shared_ptr<ContextVK> context = MockVulkanContextBuilder().Build();

  const CapabilitiesVK* capabilites_vk =
      reinterpret_cast<const CapabilitiesVK*>(context->GetCapabilities().get());
  ASSERT_NE(capabilites_vk->GetDefaultColorFormat(), PixelFormat::kUnknown);
}

}  // namespace testing
}  // namespace impeller
