// 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/vulkan/vulkan_utilities.h"
#include "flutter/fml/build_config.h"

#include <algorithm>
#include <unordered_set>

namespace vulkan {

// Whether to show Vulkan validation layer info messages in addition
// to the error messages.
bool ValidationLayerInfoMessagesEnabled() {
  return false;
}

bool ValidationErrorsFatal() {
#if OS_FUCHSIA
  return false;
#endif
  return true;
}

static std::vector<std::string> InstanceOrDeviceLayersToEnable(
    const VulkanProcTable& vk,
    VkPhysicalDevice physical_device,
    bool enable_validation_layers) {
  if (!enable_validation_layers) {
    return {};
  }

  // NOTE: The loader is sensitive to the ordering here. Please do not rearrange
  // this list.
#if OS_FUCHSIA
  // The other layers in the Fuchsia SDK seem to have a bug right now causing
  // crashes, so it is only recommended that we use VK_LAYER_KHRONOS_validation
  // until we have a confirmation that they are fixed.
  const std::vector<std::string> candidates = {"VK_LAYER_KHRONOS_validation"};
#else
  const std::vector<std::string> candidates = {
      "VK_LAYER_GOOGLE_threading",      "VK_LAYER_LUNARG_parameter_validation",
      "VK_LAYER_LUNARG_object_tracker", "VK_LAYER_LUNARG_core_validation",
      "VK_LAYER_LUNARG_device_limits",  "VK_LAYER_LUNARG_image",
      "VK_LAYER_LUNARG_swapchain",      "VK_LAYER_GOOGLE_unique_objects"};
#endif

  uint32_t count = 0;

  if (physical_device == VK_NULL_HANDLE) {
    if (VK_CALL_LOG_ERROR(vk.EnumerateInstanceLayerProperties(
            &count, nullptr)) != VK_SUCCESS) {
      return {};
    }
  } else {
    if (VK_CALL_LOG_ERROR(vk.EnumerateDeviceLayerProperties(
            physical_device, &count, nullptr)) != VK_SUCCESS) {
      return {};
    }
  }

  std::vector<VkLayerProperties> properties;
  properties.resize(count);

  if (physical_device == VK_NULL_HANDLE) {
    if (VK_CALL_LOG_ERROR(vk.EnumerateInstanceLayerProperties(
            &count, properties.data())) != VK_SUCCESS) {
      return {};
    }
  } else {
    if (VK_CALL_LOG_ERROR(vk.EnumerateDeviceLayerProperties(
            physical_device, &count, properties.data())) != VK_SUCCESS) {
      return {};
    }
  }

  std::unordered_set<std::string> available_extensions;

  for (size_t i = 0; i < count; i++) {
    available_extensions.emplace(properties[i].layerName);
  }

  std::vector<std::string> available_candidates;

  for (const auto& candidate : candidates) {
    auto found = available_extensions.find(candidate);
    if (found != available_extensions.end()) {
      available_candidates.emplace_back(candidate);
    }
  }

  return available_candidates;
}

std::vector<std::string> InstanceLayersToEnable(const VulkanProcTable& vk,
                                                bool enable_validation_layers) {
  return InstanceOrDeviceLayersToEnable(vk, VK_NULL_HANDLE,
                                        enable_validation_layers);
}

std::vector<std::string> DeviceLayersToEnable(
    const VulkanProcTable& vk,
    const VulkanHandle<VkPhysicalDevice>& physical_device,
    bool enable_validation_layers) {
  if (!physical_device) {
    return {};
  }

  return InstanceOrDeviceLayersToEnable(vk, physical_device,
                                        enable_validation_layers);
}

}  // namespace vulkan
