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

#include <iomanip>
#include <vector>

#include "flutter/fml/compiler_specific.h"
#include "flutter/vulkan/vulkan_utilities.h"

namespace vulkan {

static const VkDebugReportFlagsEXT kVulkanErrorFlags FML_ALLOW_UNUSED_TYPE =
    VK_DEBUG_REPORT_WARNING_BIT_EXT |
    VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT | VK_DEBUG_REPORT_ERROR_BIT_EXT;

static const VkDebugReportFlagsEXT kVulkanInfoFlags FML_ALLOW_UNUSED_TYPE =
    VK_DEBUG_REPORT_INFORMATION_BIT_EXT | VK_DEBUG_REPORT_DEBUG_BIT_EXT;

std::string VulkanDebugReport::DebugExtensionName() {
  return VK_EXT_DEBUG_REPORT_EXTENSION_NAME;
}

static const char* VkDebugReportFlagsEXTToString(VkDebugReportFlagsEXT flags) {
  if (flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) {
    return "Information";
  } else if (flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) {
    return "Warning";
  } else if (flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) {
    return "Performance Warning";
  } else if (flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) {
    return "Error";
  } else if (flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) {
    return "Debug";
  }
  return "UNKNOWN";
}

static const char* VkDebugReportObjectTypeEXTToString(
    VkDebugReportObjectTypeEXT type) {
  switch (type) {
    case VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT:
      return "Unknown";
    case VK_DEBUG_REPORT_OBJECT_TYPE_INSTANCE_EXT:
      return "Instance";
    case VK_DEBUG_REPORT_OBJECT_TYPE_PHYSICAL_DEVICE_EXT:
      return "Physical Device";
    case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_EXT:
      return "Device";
    case VK_DEBUG_REPORT_OBJECT_TYPE_QUEUE_EXT:
      return "Queue";
    case VK_DEBUG_REPORT_OBJECT_TYPE_SEMAPHORE_EXT:
      return "Semaphore";
    case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_BUFFER_EXT:
      return "Command Buffer";
    case VK_DEBUG_REPORT_OBJECT_TYPE_FENCE_EXT:
      return "Fence";
    case VK_DEBUG_REPORT_OBJECT_TYPE_DEVICE_MEMORY_EXT:
      return "Device Memory";
    case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT:
      return "Buffer";
    case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_EXT:
      return "Image";
    case VK_DEBUG_REPORT_OBJECT_TYPE_EVENT_EXT:
      return "Event";
    case VK_DEBUG_REPORT_OBJECT_TYPE_QUERY_POOL_EXT:
      return "Query Pool";
    case VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_VIEW_EXT:
      return "Buffer View";
    case VK_DEBUG_REPORT_OBJECT_TYPE_IMAGE_VIEW_EXT:
      return "Image_view";
    case VK_DEBUG_REPORT_OBJECT_TYPE_SHADER_MODULE_EXT:
      return "Shader Module";
    case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_CACHE_EXT:
      return "Pipeline Cache";
    case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_LAYOUT_EXT:
      return "Pipeline Layout";
    case VK_DEBUG_REPORT_OBJECT_TYPE_RENDER_PASS_EXT:
      return "Render Pass";
    case VK_DEBUG_REPORT_OBJECT_TYPE_PIPELINE_EXT:
      return "Pipeline";
    case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_LAYOUT_EXT:
      return "Descriptor Set Layout";
    case VK_DEBUG_REPORT_OBJECT_TYPE_SAMPLER_EXT:
      return "Sampler";
    case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_POOL_EXT:
      return "Descriptor Pool";
    case VK_DEBUG_REPORT_OBJECT_TYPE_DESCRIPTOR_SET_EXT:
      return "Descriptor Set";
    case VK_DEBUG_REPORT_OBJECT_TYPE_FRAMEBUFFER_EXT:
      return "Framebuffer";
    case VK_DEBUG_REPORT_OBJECT_TYPE_COMMAND_POOL_EXT:
      return "Command Pool";
    case VK_DEBUG_REPORT_OBJECT_TYPE_SURFACE_KHR_EXT:
      return "Surface";
    case VK_DEBUG_REPORT_OBJECT_TYPE_SWAPCHAIN_KHR_EXT:
      return "Swapchain";
    case VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT:
      return "Debug";
    default:
      break;
  }

  return "Unknown";
}

static VKAPI_ATTR VkBool32
OnVulkanDebugReportCallback(VkDebugReportFlagsEXT flags,
                            VkDebugReportObjectTypeEXT object_type,
                            uint64_t object,
                            size_t location,
                            int32_t message_code,
                            const char* layer_prefix,
                            const char* message,
                            void* user_data) {
  std::vector<std::pair<std::string, std::string>> items;

  items.emplace_back("Severity", VkDebugReportFlagsEXTToString(flags));

  items.emplace_back("Object Type",
                     VkDebugReportObjectTypeEXTToString(object_type));

  items.emplace_back("Object Handle", std::to_string(object));

  if (location != 0) {
    items.emplace_back("Location", std::to_string(location));
  }

  if (message_code != 0) {
    items.emplace_back("Message Code", std::to_string(message_code));
  }

  if (layer_prefix != nullptr) {
    items.emplace_back("Layer", layer_prefix);
  }

  if (message != nullptr) {
    items.emplace_back("Message", message);
  }

  size_t padding = 0;

  for (const auto& item : items) {
    padding = std::max(padding, item.first.size());
  }

  padding += 1;

  std::stringstream stream;

  stream << std::endl;

  stream << "--- Vulkan Debug Report  ----------------------------------------";

  stream << std::endl;

  for (const auto& item : items) {
    stream << "| " << std::setw(static_cast<int>(padding)) << item.first
           << std::setw(0) << ": " << item.second << std::endl;
  }

  stream << "-----------------------------------------------------------------";

  if (flags & kVulkanErrorFlags) {
    if (ValidationErrorsFatal()) {
      FML_DCHECK(false) << stream.str();
    } else {
      FML_LOG(ERROR) << stream.str();
    }
  } else {
    FML_LOG(INFO) << stream.str();
  }

  // Returning false tells the layer not to stop when the event occurs, so
  // they see the same behavior with and without validation layers enabled.
  return VK_FALSE;
}

VulkanDebugReport::VulkanDebugReport(
    const VulkanProcTable& p_vk,
    const VulkanHandle<VkInstance>& application)
    : vk(p_vk), application_(application), valid_(false) {
  if (!vk.CreateDebugReportCallbackEXT || !vk.DestroyDebugReportCallbackEXT) {
    return;
  }

  if (!application_) {
    return;
  }

  VkDebugReportFlagsEXT flags = kVulkanErrorFlags;
  if (ValidationLayerInfoMessagesEnabled())
    flags |= kVulkanInfoFlags;
  const VkDebugReportCallbackCreateInfoEXT create_info = {
      .sType = VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT,
      .pNext = nullptr,
      .flags = flags,
      .pfnCallback = &vulkan::OnVulkanDebugReportCallback,
      .pUserData = nullptr,
  };

  VkDebugReportCallbackEXT handle = VK_NULL_HANDLE;
  if (VK_CALL_LOG_ERROR(vk.CreateDebugReportCallbackEXT(
          application_, &create_info, nullptr, &handle)) != VK_SUCCESS) {
    return;
  }

  handle_ = {handle, [this](VkDebugReportCallbackEXT handle) {
               vk.DestroyDebugReportCallbackEXT(application_, handle, nullptr);
             }};

  valid_ = true;
}

VulkanDebugReport::~VulkanDebugReport() = default;

bool VulkanDebugReport::IsValid() const {
  return valid_;
}

}  // namespace vulkan
