/* Copyright (c) 2015-2017 The Khronos Group Inc.
 * Copyright (c) 2015-2017 Valve Corporation
 * Copyright (c) 2015-2017 LunarG, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Courtney Goeltzenleuchter <courtney@LunarG.com>
 * Author: Tobin Ehlis <tobin@lunarg.com>
 * Author: Mark Young <marky@lunarg.com>
 *
 */

#ifndef LAYER_LOGGING_H
#define LAYER_LOGGING_H

#include "vk_loader_layer.h"
#include "vk_layer_config.h"
#include "vk_layer_data.h"
#include "vk_layer_table.h"
#include "vk_loader_platform.h"
#include "vulkan/vk_layer.h"
#include "vk_object_types.h"
#include <signal.h>
#include <cinttypes>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <unordered_map>
#include <vector>
#include <sstream>
#include <string>

// TODO: Could be autogenerated for the specific handles for extra type safety...
template <typename HANDLE_T>
static inline uint64_t HandleToUint64(HANDLE_T *h) {
    return reinterpret_cast<uint64_t>(h);
}

static inline uint64_t HandleToUint64(uint64_t h) { return h; }

// Data we store per label for logging
typedef struct _LoggingLabelData {
    std::string name;
    float color[4];
} LoggingLabelData;

typedef struct _debug_report_data {
    VkLayerDbgFunctionNode *debug_callback_list;
    VkLayerDbgFunctionNode *default_debug_callback_list;
    VkDebugUtilsMessageSeverityFlagsEXT active_severities;
    VkDebugUtilsMessageTypeFlagsEXT active_types;
    bool g_DEBUG_REPORT;
    bool g_DEBUG_UTILS;
    std::unordered_map<uint64_t, std::string> *debugObjectNameMap;
    std::unordered_map<uint64_t, std::string> *debugUtilsObjectNameMap;
    std::unordered_map<VkQueue, std::vector<LoggingLabelData>> *debugUtilsQueueLabels;
    bool queueLabelHasInsert;
    std::unordered_map<VkCommandBuffer, std::vector<LoggingLabelData>> *debugUtilsCmdBufLabels;
    bool cmdBufLabelHasInsert;
} debug_report_data;

template debug_report_data *GetLayerDataPtr<debug_report_data>(void *data_key,
                                                               std::unordered_map<void *, debug_report_data *> &data_map);

static inline void DebugReportFlagsToAnnotFlags(VkDebugReportFlagsEXT dr_flags, bool default_flag_is_spec,
                                                VkDebugUtilsMessageSeverityFlagsEXT *da_severity,
                                                VkDebugUtilsMessageTypeFlagsEXT *da_type) {
    // All layer warnings are spec warnings currently.  At least as far as anything not specifically
    // called out.  In the future, we'll label things using the new split severity and type values.
    *da_type = VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
    *da_severity = 0;
    if ((dr_flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) != 0) {
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
    }
    if ((dr_flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) != 0) {
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT;
    }
    if ((dr_flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) != 0) {
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
    }
    if ((dr_flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) != 0) {
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
    }
    if ((dr_flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) != 0) {
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT;
    }
}

// Forward Declarations
static inline bool debug_log_msg(const debug_report_data *debug_data, VkFlags msg_flags, VkDebugReportObjectTypeEXT object_type,
                                 uint64_t src_object, size_t location, int32_t msg_code, const char *layer_prefix,
                                 const char *message, const char *text_vuid = NULL);

// Add a debug message callback node structure to the specified callback linked list
static inline void AddDebugCallbackNode(debug_report_data *debug_data, VkLayerDbgFunctionNode **list_head,
                                        VkLayerDbgFunctionNode *new_node) {
    new_node->pNext = *list_head;
    *list_head = new_node;
}

// Remove specified debug messenger node structure from the specified linked list
static inline void RemoveDebugUtilsMessenger(debug_report_data *debug_data, VkLayerDbgFunctionNode **list_head,
                                             VkDebugUtilsMessengerEXT messenger) {
    VkLayerDbgFunctionNode *cur_callback = *list_head;
    VkLayerDbgFunctionNode *prev_callback = cur_callback;
    bool matched = false;
    VkFlags local_severities = 0;
    VkFlags local_types = 0;

    while (cur_callback) {
        if (cur_callback->is_messenger && cur_callback->messenger.messenger == messenger) {
            matched = true;
            prev_callback->pNext = cur_callback->pNext;
            if (*list_head == cur_callback) {
                *list_head = cur_callback->pNext;
            }
            debug_log_msg(debug_data, VK_DEBUG_REPORT_DEBUG_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
                          reinterpret_cast<uint64_t &>(cur_callback->messenger.messenger), 0, 0, "DebugUtilsMessenger",
                          "Destroyed messenger\n");
        } else {
            matched = false;
            local_severities |= cur_callback->messenger.messageSeverity;
            local_types |= cur_callback->messenger.messageType;
        }
        prev_callback = cur_callback;
        cur_callback = cur_callback->pNext;
        if (matched) {
            free(prev_callback);
        }
    }
    debug_data->active_severities = local_severities;
    debug_data->active_types = local_types;
}

// Remove specified debug message callback node structure from the specified callback linked list
static inline void RemoveDebugUtilsMessageCallback(debug_report_data *debug_data, VkLayerDbgFunctionNode **list_head,
                                                   VkDebugReportCallbackEXT callback) {
    VkLayerDbgFunctionNode *cur_callback = *list_head;
    VkLayerDbgFunctionNode *prev_callback = cur_callback;
    bool matched = false;
    VkFlags local_severities = 0;
    VkFlags local_types = 0;

    while (cur_callback) {
        if (!cur_callback->is_messenger && cur_callback->report.msgCallback == callback) {
            matched = true;
            prev_callback->pNext = cur_callback->pNext;
            if (*list_head == cur_callback) {
                *list_head = cur_callback->pNext;
            }
            debug_log_msg(debug_data, VK_DEBUG_REPORT_DEBUG_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
                          reinterpret_cast<uint64_t &>(cur_callback->report.msgCallback), 0, 0, "DebugReport",
                          "Destroyed callback\n");
        } else {
            matched = false;
            VkFlags this_severities = 0;
            VkFlags this_types = 0;
            DebugReportFlagsToAnnotFlags(cur_callback->report.msgFlags, true, &this_severities, &this_types);
            local_severities |= this_severities;
            local_types |= this_types;
        }
        prev_callback = cur_callback;
        cur_callback = cur_callback->pNext;
        if (matched) {
            free(prev_callback);
        }
    }
    debug_data->active_severities = local_severities;
    debug_data->active_types = local_types;
}

// Removes all debug callback function nodes from the specified callback linked lists and frees their resources
static inline void RemoveAllMessageCallbacks(debug_report_data *debug_data, VkLayerDbgFunctionNode **list_head) {
    VkLayerDbgFunctionNode *current_callback = *list_head;
    VkLayerDbgFunctionNode *prev_callback = current_callback;

    while (current_callback) {
        prev_callback = current_callback->pNext;
        if (!current_callback->is_messenger) {
            debug_log_msg(debug_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
                          (uint64_t)current_callback->report.msgCallback, 0, 0, "DebugReport",
                          "Debug Report callbacks not removed before DestroyInstance");
        } else {
            debug_log_msg(debug_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT,
                          (uint64_t)current_callback->messenger.messenger, 0, 0, "Messenger",
                          "Debug messengers not removed before DestroyInstance");
        }
        free(current_callback);
        current_callback = prev_callback;
    }
    *list_head = NULL;
}

// Note that text_vuid is a default parameter, and is optional.  See the above forward declaration
static inline bool debug_log_msg(const debug_report_data *debug_data, VkFlags msg_flags, VkDebugReportObjectTypeEXT object_type,
                                 uint64_t src_object, size_t location, int32_t msg_code, const char *layer_prefix,
                                 const char *message, const char *text_vuid) {
    bool bail = false;
    VkLayerDbgFunctionNode *layer_dbg_node = NULL;

    if (debug_data->debug_callback_list != NULL) {
        layer_dbg_node = debug_data->debug_callback_list;
    } else {
        layer_dbg_node = debug_data->default_debug_callback_list;
    }

    VkDebugUtilsMessageSeverityFlagsEXT severity;
    VkDebugUtilsMessageTypeFlagsEXT types;
    VkDebugUtilsMessengerCallbackDataEXT callback_data;
    VkDebugUtilsObjectNameInfoEXT object_name_info;

    // Convert the info to the VK_EXT_debug_utils form in case we need it.
    DebugReportFlagsToAnnotFlags(msg_flags, true, &severity, &types);
    object_name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
    object_name_info.pNext = NULL;
    object_name_info.objectType = convertDebugReportObjectToCoreObject(object_type);
    object_name_info.objectHandle = (uint64_t)(uintptr_t)src_object;
    object_name_info.pObjectName = NULL;

    callback_data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
    callback_data.pNext = NULL;
    callback_data.flags = 0;
    callback_data.pMessageIdName = text_vuid;
    callback_data.messageIdNumber = msg_code;
    callback_data.pMessage = message;
    callback_data.queueLabelCount = 0;
    callback_data.pQueueLabels = NULL;
    callback_data.cmdBufLabelCount = 0;
    callback_data.pCmdBufLabels = NULL;
    callback_data.objectCount = 1;
    callback_data.pObjects = &object_name_info;

    VkDebugUtilsLabelEXT *queue_labels = nullptr;
    VkDebugUtilsLabelEXT *cmd_buf_labels = nullptr;
    std::string new_debug_report_message = "";
    std::ostringstream oss;

    if (0 != src_object) {
        oss << "Object: 0x" << std::hex << src_object;
        // If this is a queue, add any queue labels to the callback data.
        if (VK_OBJECT_TYPE_QUEUE == object_name_info.objectType) {
            auto label_iter = debug_data->debugUtilsQueueLabels->find(reinterpret_cast<VkQueue>(src_object));
            if (label_iter != debug_data->debugUtilsQueueLabels->end()) {
                queue_labels = new VkDebugUtilsLabelEXT[label_iter->second.size()];
                if (nullptr != queue_labels) {
                    // Record the labels, but record them in reverse order since we want the
                    // most recent at the top.
                    uint32_t label_size = static_cast<uint32_t>(label_iter->second.size());
                    uint32_t last_index = label_size - 1;
                    for (uint32_t label = 0; label < label_size; ++label) {
                        queue_labels[last_index - label].sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
                        queue_labels[last_index - label].pNext = nullptr;
                        queue_labels[last_index - label].pLabelName = label_iter->second[label].name.c_str();
                        queue_labels[last_index - label].color[0] = label_iter->second[label].color[0];
                        queue_labels[last_index - label].color[1] = label_iter->second[label].color[1];
                        queue_labels[last_index - label].color[2] = label_iter->second[label].color[2];
                        queue_labels[last_index - label].color[3] = label_iter->second[label].color[3];
                    }
                    callback_data.queueLabelCount = label_size;
                    callback_data.pQueueLabels = queue_labels;
                }
            }
            // If this is a command buffer, add any command buffer labels to the callback data.
        } else if (VK_OBJECT_TYPE_COMMAND_BUFFER == object_name_info.objectType) {
            auto label_iter = debug_data->debugUtilsCmdBufLabels->find(reinterpret_cast<VkCommandBuffer>(src_object));
            if (label_iter != debug_data->debugUtilsCmdBufLabels->end()) {
                cmd_buf_labels = new VkDebugUtilsLabelEXT[label_iter->second.size()];
                if (nullptr != cmd_buf_labels) {
                    // Record the labels, but record them in reverse order since we want the
                    // most recent at the top.
                    uint32_t label_size = static_cast<uint32_t>(label_iter->second.size());
                    uint32_t last_index = label_size - 1;
                    for (uint32_t label = 0; label < label_size; ++label) {
                        cmd_buf_labels[last_index - label].sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT;
                        cmd_buf_labels[last_index - label].pNext = nullptr;
                        cmd_buf_labels[last_index - label].pLabelName = label_iter->second[label].name.c_str();
                        cmd_buf_labels[last_index - label].color[0] = label_iter->second[label].color[0];
                        cmd_buf_labels[last_index - label].color[1] = label_iter->second[label].color[1];
                        cmd_buf_labels[last_index - label].color[2] = label_iter->second[label].color[2];
                        cmd_buf_labels[last_index - label].color[3] = label_iter->second[label].color[3];
                    }
                    callback_data.cmdBufLabelCount = label_size;
                    callback_data.pCmdBufLabels = cmd_buf_labels;
                }
            }
        }
        // Look for any debug utils or marker names to use for this object
        object_name_info.pObjectName = NULL;
        auto utils_name_iter = debug_data->debugUtilsObjectNameMap->find(src_object);
        if (utils_name_iter != debug_data->debugUtilsObjectNameMap->end()) {
            object_name_info.pObjectName = utils_name_iter->second.c_str();
        } else {
            auto marker_name_iter = debug_data->debugObjectNameMap->find(src_object);
            if (marker_name_iter != debug_data->debugObjectNameMap->end()) {
                object_name_info.pObjectName = marker_name_iter->second.c_str();
            }
        }
        if (NULL != object_name_info.pObjectName) {
            oss << " (Name = " << object_name_info.pObjectName << " : Type = ";
        } else {
            oss << " (Type = ";
        }
        oss << std::to_string(object_type) << ")";
    } else {
        oss << "Object: VK_NULL_HANDLE (Type = " << std::to_string(object_type) << ")";
    }
    new_debug_report_message += oss.str();
    new_debug_report_message += " | ";
    new_debug_report_message += message;

    while (layer_dbg_node) {
        // If the app uses the VK_EXT_debug_report extension, call all of those registered callbacks.
        if (!layer_dbg_node->is_messenger && (layer_dbg_node->report.msgFlags & msg_flags)) {
            if (text_vuid != nullptr) {
                // If a text vuid is supplied for the old debug report extension, prepend it to the message string
                new_debug_report_message.insert(0, " ] ");
                new_debug_report_message.insert(0, text_vuid);
                new_debug_report_message.insert(0, " [ ");
            }

            if (layer_dbg_node->report.pfnMsgCallback(msg_flags, object_type, src_object, location, msg_code, layer_prefix,
                                                      new_debug_report_message.c_str(), layer_dbg_node->pUserData)) {
                bail = true;
            }
            // If the app uses the VK_EXT_debug_utils extension, call all of those registered callbacks.
        } else if (layer_dbg_node->is_messenger && (layer_dbg_node->messenger.messageSeverity & severity) &&
                   (layer_dbg_node->messenger.messageType & types)) {
            if (layer_dbg_node->messenger.pfnUserCallback(static_cast<VkDebugUtilsMessageSeverityFlagBitsEXT>(severity), types,
                                                          &callback_data, layer_dbg_node->pUserData)) {
                bail = true;
            }
        }
        layer_dbg_node = layer_dbg_node->pNext;
    }

    if (nullptr != queue_labels) {
        delete[] queue_labels;
    }
    if (nullptr != cmd_buf_labels) {
        delete[] cmd_buf_labels;
    }

    return bail;
}

static inline void DebugAnnotFlagsToReportFlags(VkDebugUtilsMessageSeverityFlagBitsEXT da_severity,
                                                VkDebugUtilsMessageTypeFlagsEXT da_type, VkDebugReportFlagsEXT *dr_flags) {
    *dr_flags = 0;

    if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) != 0) {
        *dr_flags |= VK_DEBUG_REPORT_ERROR_BIT_EXT;
    } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) != 0) {
        if ((da_type & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT) != 0) {
            *dr_flags |= VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
        } else {
            *dr_flags |= VK_DEBUG_REPORT_WARNING_BIT_EXT;
        }
    } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) != 0) {
        *dr_flags |= VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
    } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) != 0) {
        *dr_flags |= VK_DEBUG_REPORT_DEBUG_BIT_EXT;
    }
}

static inline bool debug_messenger_log_msg(const debug_report_data *debug_data,
                                           VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
                                           VkDebugUtilsMessageTypeFlagsEXT message_type,
                                           VkDebugUtilsMessengerCallbackDataEXT *callback_data,
                                           const VkDebugUtilsMessengerEXT *messenger) {
    bool bail = false;
    VkLayerDbgFunctionNode *layer_dbg_node = NULL;

    if (debug_data->debug_callback_list != NULL) {
        layer_dbg_node = debug_data->debug_callback_list;
    } else {
        layer_dbg_node = debug_data->default_debug_callback_list;
    }

    VkDebugReportFlagsEXT object_flags = 0;

    DebugAnnotFlagsToReportFlags(message_severity, message_type, &object_flags);

    VkDebugUtilsObjectNameInfoEXT object_name_info;
    object_name_info.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT;
    object_name_info.pNext = NULL;
    object_name_info.objectType = VK_OBJECT_TYPE_DEBUG_UTILS_MESSENGER_EXT;
    object_name_info.objectHandle = HandleToUint64(*messenger);
    object_name_info.pObjectName = NULL;
    callback_data->pObjects = &object_name_info;
    callback_data->objectCount = 1;

    while (layer_dbg_node) {
        if (layer_dbg_node->is_messenger && (layer_dbg_node->messenger.messageSeverity & message_severity) &&
            (layer_dbg_node->messenger.messageType & message_type)) {
            auto it = debug_data->debugUtilsObjectNameMap->find(object_name_info.objectHandle);
            if (it != debug_data->debugUtilsObjectNameMap->end()) {
                object_name_info.pObjectName = it->second.c_str();
            }
            if (layer_dbg_node->messenger.pfnUserCallback(message_severity, message_type, callback_data,
                                                          layer_dbg_node->pUserData)) {
                bail = true;
            }
        } else if (!layer_dbg_node->is_messenger && layer_dbg_node->report.msgFlags & object_flags) {
            auto it = debug_data->debugObjectNameMap->find(callback_data->pObjects[0].objectHandle);
            VkDebugReportObjectTypeEXT object_type = convertCoreObjectToDebugReportObject(callback_data->pObjects[0].objectType);
            if (it == debug_data->debugObjectNameMap->end()) {
                if (layer_dbg_node->report.pfnMsgCallback(object_flags, object_type, callback_data->pObjects[0].objectHandle, 0,
                                                          callback_data->messageIdNumber, callback_data->pMessageIdName,
                                                          callback_data->pMessage, layer_dbg_node->pUserData)) {
                    bail = true;
                }
            } else {
                std::string newMsg = "SrcObject name = ";
                newMsg.append(it->second.c_str());
                newMsg.append(" ");
                newMsg.append(callback_data->pMessage);
                if (layer_dbg_node->report.pfnMsgCallback(object_flags, object_type, callback_data->pObjects[0].objectHandle, 0,
                                                          callback_data->messageIdNumber, callback_data->pMessageIdName,
                                                          newMsg.c_str(), layer_dbg_node->pUserData)) {
                    bail = true;
                }
            }
        }
        layer_dbg_node = layer_dbg_node->pNext;
    }

    return bail;
}

static inline debug_report_data *debug_utils_create_instance(
    VkLayerInstanceDispatchTable *table, VkInstance inst, uint32_t extension_count,
    const char *const *enabled_extensions)  // layer or extension name to be enabled
{
    debug_report_data *debug_data = (debug_report_data *)malloc(sizeof(debug_report_data));
    if (!debug_data) return NULL;

    memset(debug_data, 0, sizeof(debug_report_data));
    for (uint32_t i = 0; i < extension_count; i++) {
        // TODO: Check other property fields
        if (strcmp(enabled_extensions[i], VK_EXT_DEBUG_REPORT_EXTENSION_NAME) == 0) {
            debug_data->g_DEBUG_REPORT = true;
        } else if (strcmp(enabled_extensions[i], VK_EXT_DEBUG_UTILS_EXTENSION_NAME) == 0) {
            debug_data->g_DEBUG_UTILS = true;
        }
    }
    debug_data->debugObjectNameMap = new std::unordered_map<uint64_t, std::string>;
    debug_data->debugUtilsObjectNameMap = new std::unordered_map<uint64_t, std::string>;
    debug_data->debugUtilsQueueLabels = new std::unordered_map<VkQueue, std::vector<LoggingLabelData>>;
    debug_data->debugUtilsCmdBufLabels = new std::unordered_map<VkCommandBuffer, std::vector<LoggingLabelData>>;
    debug_data->queueLabelHasInsert = false;
    debug_data->cmdBufLabelHasInsert = false;
    return debug_data;
}

static inline void layer_debug_utils_destroy_instance(debug_report_data *debug_data) {
    if (debug_data) {
        RemoveAllMessageCallbacks(debug_data, &debug_data->default_debug_callback_list);
        RemoveAllMessageCallbacks(debug_data, &debug_data->debug_callback_list);
        delete debug_data->debugObjectNameMap;
        delete debug_data->debugUtilsObjectNameMap;
        delete debug_data->debugUtilsQueueLabels;
        delete debug_data->debugUtilsCmdBufLabels;
        free(debug_data);
    }
}

static inline debug_report_data *layer_debug_utils_create_device(debug_report_data *instance_debug_data, VkDevice device) {
    // DEBUG_REPORT shares data between Instance and Device,
    // so just return instance's data pointer
    return instance_debug_data;
}

static inline void layer_debug_utils_destroy_device(VkDevice device) {
    // Nothing to do since we're using instance data record
}

static inline void layer_destroy_messenger_callback(debug_report_data *debug_data, VkDebugUtilsMessengerEXT messenger,
                                                    const VkAllocationCallbacks *allocator) {
    RemoveDebugUtilsMessenger(debug_data, &debug_data->debug_callback_list, messenger);
    RemoveDebugUtilsMessenger(debug_data, &debug_data->default_debug_callback_list, messenger);
}

static inline VkResult layer_create_messenger_callback(debug_report_data *debug_data, bool default_callback,
                                                       const VkDebugUtilsMessengerCreateInfoEXT *create_info,
                                                       const VkAllocationCallbacks *allocator,
                                                       VkDebugUtilsMessengerEXT *messenger) {
    VkLayerDbgFunctionNode *pNewDbgFuncNode = (VkLayerDbgFunctionNode *)malloc(sizeof(VkLayerDbgFunctionNode));
    if (!pNewDbgFuncNode) return VK_ERROR_OUT_OF_HOST_MEMORY;
    memset(pNewDbgFuncNode, 0, sizeof(VkLayerDbgFunctionNode));
    pNewDbgFuncNode->is_messenger = true;

    // Handle of 0 is logging_callback so use allocated Node address as unique handle
    if (!(*messenger)) *messenger = (VkDebugUtilsMessengerEXT)pNewDbgFuncNode;
    pNewDbgFuncNode->messenger.messenger = *messenger;
    pNewDbgFuncNode->messenger.pfnUserCallback = create_info->pfnUserCallback;
    pNewDbgFuncNode->messenger.messageSeverity = create_info->messageSeverity;
    pNewDbgFuncNode->messenger.messageType = create_info->messageType;
    pNewDbgFuncNode->pUserData = create_info->pUserData;

    debug_data->active_severities |= create_info->messageSeverity;
    debug_data->active_types |= create_info->messageType;
    if (default_callback) {
        AddDebugCallbackNode(debug_data, &debug_data->default_debug_callback_list, pNewDbgFuncNode);
    } else {
        AddDebugCallbackNode(debug_data, &debug_data->debug_callback_list, pNewDbgFuncNode);
    }

    VkDebugUtilsMessengerCallbackDataEXT callback_data = {};
    callback_data.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CALLBACK_DATA_EXT;
    callback_data.pNext = NULL;
    callback_data.flags = 0;
    callback_data.pMessageIdName = "Layer Internal Message";
    callback_data.messageIdNumber = 0;
    callback_data.pMessage = "Added messenger";
    callback_data.queueLabelCount = 0;
    callback_data.pQueueLabels = NULL;
    callback_data.cmdBufLabelCount = 0;
    callback_data.pCmdBufLabels = NULL;
    callback_data.objectCount = 0;
    callback_data.pObjects = NULL;
    debug_messenger_log_msg(debug_data, VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT,
                            VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT, &callback_data, messenger);
    return VK_SUCCESS;
}

static inline void layer_destroy_report_callback(debug_report_data *debug_data, VkDebugReportCallbackEXT callback,
                                                 const VkAllocationCallbacks *allocator) {
    RemoveDebugUtilsMessageCallback(debug_data, &debug_data->debug_callback_list, callback);
    RemoveDebugUtilsMessageCallback(debug_data, &debug_data->default_debug_callback_list, callback);
}

static inline VkResult layer_create_report_callback(debug_report_data *debug_data, bool default_callback,
                                                    const VkDebugReportCallbackCreateInfoEXT *create_info,
                                                    const VkAllocationCallbacks *allocator, VkDebugReportCallbackEXT *callback) {
    VkLayerDbgFunctionNode *pNewDbgFuncNode = (VkLayerDbgFunctionNode *)malloc(sizeof(VkLayerDbgFunctionNode));
    if (!pNewDbgFuncNode) {
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
    memset(pNewDbgFuncNode, 0, sizeof(VkLayerDbgFunctionNode));
    pNewDbgFuncNode->is_messenger = false;

    // Handle of 0 is logging_callback so use allocated Node address as unique handle
    if (!(*callback)) *callback = (VkDebugReportCallbackEXT)pNewDbgFuncNode;
    pNewDbgFuncNode->report.msgCallback = *callback;
    pNewDbgFuncNode->report.pfnMsgCallback = create_info->pfnCallback;
    pNewDbgFuncNode->report.msgFlags = create_info->flags;
    pNewDbgFuncNode->pUserData = create_info->pUserData;

    VkFlags local_severity = 0;
    VkFlags local_type = 0;
    DebugReportFlagsToAnnotFlags(create_info->flags, true, &local_severity, &local_type);
    debug_data->active_severities |= local_severity;
    debug_data->active_types |= local_type;
    if (default_callback) {
        AddDebugCallbackNode(debug_data, &debug_data->default_debug_callback_list, pNewDbgFuncNode);
    } else {
        AddDebugCallbackNode(debug_data, &debug_data->debug_callback_list, pNewDbgFuncNode);
    }

    debug_log_msg(debug_data, VK_DEBUG_REPORT_DEBUG_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_DEBUG_REPORT_EXT, (uint64_t)*callback, 0,
                  0, "DebugReport", "Added callback");
    return VK_SUCCESS;
}

static inline PFN_vkVoidFunction debug_utils_get_instance_proc_addr(debug_report_data *debug_data, const char *func_name) {
    if (!debug_data) {
        return NULL;
    }
    if (debug_data->g_DEBUG_REPORT) {
        if (!strcmp(func_name, "vkCreateDebugReportCallbackEXT")) {
            return (PFN_vkVoidFunction)vkCreateDebugReportCallbackEXT;
        }
        if (!strcmp(func_name, "vkDestroyDebugReportCallbackEXT")) {
            return (PFN_vkVoidFunction)vkDestroyDebugReportCallbackEXT;
        }
        if (!strcmp(func_name, "vkDebugReportMessageEXT")) {
            return (PFN_vkVoidFunction)vkDebugReportMessageEXT;
        }
    }
    if (debug_data->g_DEBUG_UTILS) {
        if (!strcmp(func_name, "vkCreateDebugUtilsMessengerEXT")) {
            return (PFN_vkVoidFunction)vkCreateDebugUtilsMessengerEXT;
        }
        if (!strcmp(func_name, "vkDestroyDebugUtilsMessengerEXT")) {
            return (PFN_vkVoidFunction)vkDestroyDebugUtilsMessengerEXT;
        }
        if (!strcmp(func_name, "vkSubmitDebugUtilsMessageEXT")) {
            return (PFN_vkVoidFunction)vkSubmitDebugUtilsMessageEXT;
        }
    }
    return NULL;
}

// This utility (called at vkCreateInstance() time), looks at a pNext chain.
// It counts any VkDebugReportCallbackCreateInfoEXT structs that it finds.  It
// then allocates an array that can hold that many structs, as well as that
// many VkDebugReportCallbackEXT handles.  It then copies each
// VkDebugReportCallbackCreateInfoEXT, and initializes each handle.
static inline VkResult layer_copy_tmp_report_callbacks(const void *pChain, uint32_t *num_callbacks,
                                                       VkDebugReportCallbackCreateInfoEXT **infos,
                                                       VkDebugReportCallbackEXT **callbacks) {
    uint32_t n = *num_callbacks = 0;

    const void *pNext = pChain;
    while (pNext) {
        // 1st, count the number VkDebugReportCallbackCreateInfoEXT:
        if (((VkDebugReportCallbackCreateInfoEXT *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
            n++;
        }
        pNext = (void *)((VkDebugReportCallbackCreateInfoEXT *)pNext)->pNext;
    }
    if (n == 0) {
        return VK_SUCCESS;
    }

    // 2nd, allocate memory for each VkDebugReportCallbackCreateInfoEXT:
    VkDebugReportCallbackCreateInfoEXT *pInfos = *infos =
        ((VkDebugReportCallbackCreateInfoEXT *)malloc(n * sizeof(VkDebugReportCallbackCreateInfoEXT)));
    if (!pInfos) {
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
    // 3rd, allocate memory for a unique handle for each callback:
    VkDebugReportCallbackEXT *pCallbacks = *callbacks = ((VkDebugReportCallbackEXT *)malloc(n * sizeof(VkDebugReportCallbackEXT)));
    if (!pCallbacks) {
        free(pInfos);
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
    // 4th, copy each VkDebugReportCallbackCreateInfoEXT for use by
    // vkDestroyInstance, and assign a unique handle to each callback (just
    // use the address of the copied VkDebugReportCallbackCreateInfoEXT):
    pNext = pChain;
    while (pNext) {
        if (((VkInstanceCreateInfo *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT) {
            memcpy(pInfos, pNext, sizeof(VkDebugReportCallbackCreateInfoEXT));
            *pCallbacks++ = (VkDebugReportCallbackEXT)pInfos++;
        }
        pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext;
    }

    *num_callbacks = n;
    return VK_SUCCESS;
}

// This utility frees the arrays allocated by layer_copy_tmp_report_callbacks()
static inline void layer_free_tmp_report_callbacks(VkDebugReportCallbackCreateInfoEXT *infos, VkDebugReportCallbackEXT *callbacks) {
    free(infos);
    free(callbacks);
}

// This utility enables all of the VkDebugReportCallbackCreateInfoEXT structs
// that were copied by layer_copy_tmp_report_callbacks()
static inline VkResult layer_enable_tmp_report_callbacks(debug_report_data *debug_data, uint32_t num_callbacks,
                                                         VkDebugReportCallbackCreateInfoEXT *infos,
                                                         VkDebugReportCallbackEXT *callbacks) {
    VkResult rtn = VK_SUCCESS;
    for (uint32_t i = 0; i < num_callbacks; i++) {
        rtn = layer_create_report_callback(debug_data, false, &infos[i], NULL, &callbacks[i]);
        if (rtn != VK_SUCCESS) {
            for (uint32_t j = 0; j < i; j++) {
                layer_destroy_report_callback(debug_data, callbacks[j], NULL);
            }
            return rtn;
        }
    }
    return rtn;
}

// This utility disables all of the VkDebugReportCallbackCreateInfoEXT structs
// that were copied by layer_copy_tmp_report_callbacks()
static inline void layer_disable_tmp_report_callbacks(debug_report_data *debug_data, uint32_t num_callbacks,
                                                      VkDebugReportCallbackEXT *callbacks) {
    for (uint32_t i = 0; i < num_callbacks; i++) {
        layer_destroy_report_callback(debug_data, callbacks[i], NULL);
    }
}

// This utility (called at vkCreateInstance() time), looks at a pNext chain.
// It counts any VkDebugUtilsMessengerCreateInfoEXT structs that it finds.  It
// then allocates an array that can hold that many structs, as well as that
// many VkDebugUtilsMessengerEXT handles.  It then copies each
// VkDebugUtilsMessengerCreateInfoEXT, and initializes each handle.
static inline VkResult layer_copy_tmp_debug_messengers(const void *pChain, uint32_t *num_messengers,
                                                       VkDebugUtilsMessengerCreateInfoEXT **infos,
                                                       VkDebugUtilsMessengerEXT **messengers) {
    uint32_t n = *num_messengers = 0;

    const void *pNext = pChain;
    while (pNext) {
        // 1st, count the number VkDebugUtilsMessengerCreateInfoEXT:
        if (((VkDebugUtilsMessengerCreateInfoEXT *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
            n++;
        }
        pNext = (void *)((VkDebugUtilsMessengerCreateInfoEXT *)pNext)->pNext;
    }
    if (n == 0) {
        return VK_SUCCESS;
    }

    // 2nd, allocate memory for each VkDebugUtilsMessengerCreateInfoEXT:
    VkDebugUtilsMessengerCreateInfoEXT *pInfos = *infos =
        ((VkDebugUtilsMessengerCreateInfoEXT *)malloc(n * sizeof(VkDebugUtilsMessengerCreateInfoEXT)));
    if (!pInfos) {
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
    // 3rd, allocate memory for a unique handle for each messenger:
    VkDebugUtilsMessengerEXT *pMessengers = *messengers =
        ((VkDebugUtilsMessengerEXT *)malloc(n * sizeof(VkDebugUtilsMessengerEXT)));
    if (!pMessengers) {
        free(pInfos);
        return VK_ERROR_OUT_OF_HOST_MEMORY;
    }
    // 4th, copy each VkDebugUtilsMessengerCreateInfoEXT for use by
    // vkDestroyInstance, and assign a unique handle to each callback (just
    // use the address of the copied VkDebugUtilsMessengerCreateInfoEXT):
    pNext = pChain;
    while (pNext) {
        if (((VkInstanceCreateInfo *)pNext)->sType == VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT) {
            memcpy(pInfos, pNext, sizeof(VkDebugUtilsMessengerCreateInfoEXT));
            *pMessengers++ = (VkDebugUtilsMessengerEXT)pInfos++;
        }
        pNext = (void *)((VkInstanceCreateInfo *)pNext)->pNext;
    }

    *num_messengers = n;
    return VK_SUCCESS;
}

// This utility frees the arrays allocated by layer_copy_tmp_debug_messengers()
static inline void layer_free_tmp_debug_messengers(VkDebugUtilsMessengerCreateInfoEXT *infos,
                                                   VkDebugUtilsMessengerEXT *messengers) {
    free(infos);
    free(messengers);
}

// This utility enables all of the VkDebugUtilsMessengerCreateInfoEXT structs
// that were copied by layer_copy_tmp_debug_messengers()
static inline VkResult layer_enable_tmp_debug_messengers(debug_report_data *debug_data, uint32_t num_messengers,
                                                         VkDebugUtilsMessengerCreateInfoEXT *infos,
                                                         VkDebugUtilsMessengerEXT *messengers) {
    VkResult rtn = VK_SUCCESS;
    for (uint32_t i = 0; i < num_messengers; i++) {
        rtn = layer_create_messenger_callback(debug_data, false, &infos[i], NULL, &messengers[i]);
        if (rtn != VK_SUCCESS) {
            for (uint32_t j = 0; j < i; j++) {
                layer_destroy_messenger_callback(debug_data, messengers[j], NULL);
            }
            return rtn;
        }
    }
    return rtn;
}

// This utility disables all of the VkDebugUtilsMessengerCreateInfoEXT structs
// that were copied by layer_copy_tmp_debug_messengers()
static inline void layer_disable_tmp_debug_messengers(debug_report_data *debug_data, uint32_t num_messengers,
                                                      VkDebugUtilsMessengerEXT *messengers) {
    for (uint32_t i = 0; i < num_messengers; i++) {
        layer_destroy_messenger_callback(debug_data, messengers[i], NULL);
    }
}

// Checks if the message will get logged.
// Allows layer to defer collecting & formating data if the
// message will be discarded.
static inline bool will_log_msg(debug_report_data *debug_data, VkFlags msg_flags) {
    VkFlags local_severity = 0;
    VkFlags local_type = 0;
    DebugReportFlagsToAnnotFlags(msg_flags, true, &local_severity, &local_type);
    if (!debug_data || !(debug_data->active_severities & local_severity) || !(debug_data->active_types & local_type)) {
        // Message is not wanted
        return false;
    }

    return true;
}
#ifndef WIN32
static inline int string_sprintf(std::string *output, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
#endif
static inline int string_sprintf(std::string *output, const char *fmt, ...) {
    std::string &formatted = *output;
    va_list argptr;
    va_start(argptr, fmt);
    int reserve = vsnprintf(nullptr, 0, fmt, argptr);
    va_end(argptr);
    formatted.reserve(reserve + 1);
    va_start(argptr, fmt);
    int result = vsnprintf((char *)formatted.data(), formatted.capacity(), fmt, argptr);
    va_end(argptr);
    assert(result == reserve);
    return result;
}

#ifdef WIN32
static inline int vasprintf(char **strp, char const *fmt, va_list ap) {
    *strp = nullptr;
    int size = _vscprintf(fmt, ap);
    if (size >= 0) {
        *strp = (char *)malloc(size + 1);
        if (!*strp) {
            return -1;
        }
        _vsnprintf(*strp, size + 1, fmt, ap);
    }
    return size;
}
#endif

// Output log message via DEBUG_REPORT. Takes format and variable arg list so that output string is only computed if a message
// needs to be logged
#ifndef WIN32
static inline bool log_msg(const debug_report_data *debug_data, VkFlags msg_flags, VkDebugReportObjectTypeEXT object_type,
                           uint64_t src_object, int32_t msg_code, const char *format, ...) __attribute__((format(printf, 6, 7)));
static inline bool log_msg(const debug_report_data *debug_data, VkFlags msg_flags, VkDebugReportObjectTypeEXT object_type,
                           uint64_t src_object, std::string vuid_text, const char *format, ...)
    __attribute__((format(printf, 6, 7)));
#endif
static inline bool log_msg(const debug_report_data *debug_data, VkFlags msg_flags, VkDebugReportObjectTypeEXT object_type,
                           uint64_t src_object, int32_t msg_code, const char *format, ...) {
    VkFlags local_severity = 0;
    VkFlags local_type = 0;
    DebugReportFlagsToAnnotFlags(msg_flags, true, &local_severity, &local_type);
    if (!debug_data || !(debug_data->active_severities & local_severity) || !(debug_data->active_types & local_type)) {
        // Message is not wanted
        return false;
    }

    va_list argptr;
    va_start(argptr, format);
    char *str;
    if (-1 == vasprintf(&str, format, argptr)) {
        // On failure, glibc vasprintf leaves str undefined
        str = nullptr;
    }
    va_end(argptr);

    std::string str_plus_spec_text(str);

    bool result = debug_log_msg(debug_data, msg_flags, object_type, src_object, 0, msg_code, "Validation",
                                str_plus_spec_text.c_str() ? str_plus_spec_text.c_str() : "Allocation failure");
    free(str);
    return result;
}

// Overload of log_msg that takes a VUID string in place of a numerical VUID abstraction
static inline bool log_msg(const debug_report_data *debug_data, VkFlags msg_flags, VkDebugReportObjectTypeEXT object_type,
                           uint64_t src_object, std::string vuid_text, const char *format, ...) {
    VkFlags local_severity = 0;
    VkFlags local_type = 0;
    DebugReportFlagsToAnnotFlags(msg_flags, true, &local_severity, &local_type);
    if (!debug_data || !(debug_data->active_severities & local_severity) || !(debug_data->active_types & local_type)) {
        // Message is not wanted
        return false;
    }

    va_list argptr;
    va_start(argptr, format);
    char *str;
    if (-1 == vasprintf(&str, format, argptr)) {
        // On failure, glibc vasprintf leaves str undefined
        str = nullptr;
    }
    va_end(argptr);

    std::string str_plus_spec_text(str);

    // Append layer prefix with VUID string, pass in UNDEFINED for numerical VUID
    static const int UNDEFINED_VUID = -1;
    bool result = debug_log_msg(debug_data, msg_flags, object_type, src_object, 0, UNDEFINED_VUID, "Validation",
                                str_plus_spec_text.c_str() ? str_plus_spec_text.c_str() : "Allocation failure", vuid_text.c_str());

    free(str);
    return result;
}

static inline VKAPI_ATTR VkBool32 VKAPI_CALL report_log_callback(VkFlags msg_flags, VkDebugReportObjectTypeEXT obj_type,
                                                                 uint64_t src_object, size_t location, int32_t msg_code,
                                                                 const char *layer_prefix, const char *message, void *user_data) {
    char msg_flag_string[30];

    PrintMessageFlags(msg_flags, msg_flag_string);

    fprintf((FILE *)user_data, "%s(%s): msg_code: %d: %s\n", layer_prefix, msg_flag_string, msg_code, message);
    fflush((FILE *)user_data);

    return false;
}

static inline VKAPI_ATTR VkBool32 VKAPI_CALL report_win32_debug_output_msg(VkFlags msg_flags, VkDebugReportObjectTypeEXT obj_type,
                                                                           uint64_t src_object, size_t location, int32_t msg_code,
                                                                           const char *layer_prefix, const char *message,
                                                                           void *user_data) {
#ifdef WIN32
    char msg_flag_string[30];
    char buf[2048];

    PrintMessageFlags(msg_flags, msg_flag_string);
    _snprintf(buf, sizeof(buf) - 1, "%s (%s): msg_code: %d: %s\n", layer_prefix, msg_flag_string, msg_code, message);

    OutputDebugString(buf);
#endif

    return false;
}

static inline VKAPI_ATTR VkBool32 VKAPI_CALL DebugBreakCallback(VkFlags msgFlags, VkDebugReportObjectTypeEXT obj_type,
                                                                uint64_t src_object, size_t location, int32_t msg_code,
                                                                const char *layer_prefix, const char *message, void *user_data) {
#ifdef WIN32
    DebugBreak();
#else
    raise(SIGTRAP);
#endif

    return false;
}

static inline VKAPI_ATTR VkBool32 VKAPI_CALL messenger_log_callback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
                                                                    VkDebugUtilsMessageTypeFlagsEXT message_type,
                                                                    const VkDebugUtilsMessengerCallbackDataEXT *callback_data,
                                                                    void *user_data) {
    char msg_severity[30];
    char msg_type[30];

    PrintMessageSeverity(message_severity, msg_severity);
    PrintMessageType(message_type, msg_type);

    fprintf((FILE *)user_data, "%s(%s / %s): msgNum: %d - %s\n", callback_data->pMessageIdName, msg_severity, msg_type,
            callback_data->messageIdNumber, callback_data->pMessage);
    fprintf((FILE *)user_data, "    Objects: %d\n", callback_data->objectCount);
    for (uint32_t obj = 0; obj < callback_data->objectCount; ++obj) {
        fprintf((FILE *)user_data, "       [%d] 0x%" PRIx64 ", type: %d, name: %s\n", obj,
                callback_data->pObjects[obj].objectHandle, callback_data->pObjects[obj].objectType,
                callback_data->pObjects[obj].pObjectName);
    }
    fflush((FILE *)user_data);

    return false;
}

static inline VKAPI_ATTR VkBool32 VKAPI_CALL messenger_win32_debug_output_msg(
    VkDebugUtilsMessageSeverityFlagBitsEXT message_severity, VkDebugUtilsMessageTypeFlagsEXT message_type,
    const VkDebugUtilsMessengerCallbackDataEXT *callback_data, void *user_data) {
#ifdef WIN32
    char buf[2048];
    char msg_severity[30];
    char msg_type[30];

    PrintMessageSeverity(message_severity, msg_severity);
    PrintMessageType(message_type, msg_type);

    size_t buffer_space = sizeof(buf) - 1;
    size_t remaining_space = buffer_space;
    _snprintf(buf, sizeof(buf) - 1, "%s(%s / %s): msgNum: %d - %s\n", callback_data->pMessageIdName, msg_severity, msg_type,
              callback_data->messageIdNumber, callback_data->pMessage);
    remaining_space = buffer_space - strlen(buf);
    _snprintf(buf, remaining_space, "    Objects: %d\n", callback_data->objectCount);
    for (uint32_t obj = 0; obj < callback_data->objectCount; ++obj) {
        remaining_space = buffer_space - strlen(buf);
        if (remaining_space > 0) {
            _snprintf(buf, remaining_space, "       [%d] 0x%" PRIx64 ", type: %d, name: %s\n", obj,
                      callback_data->pObjects[obj].objectHandle, callback_data->pObjects[obj].objectType,
                      callback_data->pObjects[obj].pObjectName);
        }
    }
    OutputDebugString(buf);
#endif

    return false;
}

// This utility converts from the VkDebugUtilsLabelEXT structure into the logging version of the structure.
// In the logging version, we only record what we absolutely need to convey back to the callbacks.
static inline void InsertLabelIntoLog(const VkDebugUtilsLabelEXT *utils_label, std::vector<LoggingLabelData> &log_vector) {
    LoggingLabelData log_label_data = {};
    log_label_data.name = utils_label->pLabelName;
    log_label_data.color[0] = utils_label->color[0];
    log_label_data.color[1] = utils_label->color[1];
    log_label_data.color[2] = utils_label->color[2];
    log_label_data.color[3] = utils_label->color[3];
    log_vector.push_back(log_label_data);
}

static inline void BeginQueueDebugUtilsLabel(debug_report_data *report_data, VkQueue queue,
                                             const VkDebugUtilsLabelEXT *label_info) {
    if (nullptr != label_info && nullptr != label_info->pLabelName) {
        auto label_iter = report_data->debugUtilsQueueLabels->find(queue);
        if (label_iter == report_data->debugUtilsQueueLabels->end()) {
            std::vector<LoggingLabelData> new_queue_labels;
            InsertLabelIntoLog(label_info, new_queue_labels);
            report_data->debugUtilsQueueLabels->insert({queue, new_queue_labels});
        } else {
            // If the last thing was a label insert, we need to pop it off of the label vector before any
            // changes. This is because a label added with "vkQueueInsertDebugUtilsLabelEXT" is only a
            // temporary location that exists until the next operation occurs.  In this case, a new
            // "vkQueueBeginDebugUtilsLabelEXT" has occurred erasing the previous inserted label.
            if (report_data->queueLabelHasInsert) {
                report_data->queueLabelHasInsert = false;
                label_iter->second.pop_back();
            }
            InsertLabelIntoLog(label_info, label_iter->second);
        }
    }
}

static inline void EndQueueDebugUtilsLabel(debug_report_data *report_data, VkQueue queue) {
    auto label_iter = report_data->debugUtilsQueueLabels->find(queue);
    if (label_iter != report_data->debugUtilsQueueLabels->end()) {
        // If the last thing was a label insert, we need to pop it off of the label vector before any
        // changes. This is because a label added with "vkQueueInsertDebugUtilsLabelEXT" is only a
        // temporary location that exists until the next operation occurs.  In this case, a
        // "vkQueueEndDebugUtilsLabelEXT" has occurred erasing the inserted label.
        if (report_data->queueLabelHasInsert) {
            report_data->queueLabelHasInsert = false;
            label_iter->second.pop_back();
        }
        // Now pop the normal item
        label_iter->second.pop_back();
    }
}

static inline void InsertQueueDebugUtilsLabel(debug_report_data *report_data, VkQueue queue,
                                              const VkDebugUtilsLabelEXT *label_info) {
    if (nullptr != label_info && nullptr != label_info->pLabelName) {
        auto label_iter = report_data->debugUtilsQueueLabels->find(queue);
        if (label_iter == report_data->debugUtilsQueueLabels->end()) {
            std::vector<LoggingLabelData> new_queue_labels;
            InsertLabelIntoLog(label_info, new_queue_labels);
            report_data->debugUtilsQueueLabels->insert({queue, new_queue_labels});
        } else {
            // If the last thing was a label insert, we need to pop it off of the label vector before any
            // changes. This is because a label added with "vkQueueInsertDebugUtilsLabelEXT" is only a
            // temporary location that exists until the next operation occurs.  In this case, a new
            // "vkQueueInsertDebugUtilsLabelEXT" has occurred erasing the previous inserted label.
            if (report_data->queueLabelHasInsert) {
                label_iter->second.pop_back();
            }
            // Insert this new label and mark it as one that has been "inserted" so we can remove it on
            // the next queue label operation.
            InsertLabelIntoLog(label_info, label_iter->second);
            report_data->queueLabelHasInsert = true;
        }
    }
}

static inline void BeginCmdDebugUtilsLabel(debug_report_data *report_data, VkCommandBuffer command_buffer,
                                           const VkDebugUtilsLabelEXT *label_info) {
    if (nullptr != label_info && nullptr != label_info->pLabelName) {
        auto label_iter = report_data->debugUtilsCmdBufLabels->find(command_buffer);
        if (label_iter == report_data->debugUtilsCmdBufLabels->end()) {
            std::vector<LoggingLabelData> new_cmdbuf_labels;
            InsertLabelIntoLog(label_info, new_cmdbuf_labels);
            report_data->debugUtilsCmdBufLabels->insert({command_buffer, new_cmdbuf_labels});
        } else {
            // If the last thing was a label insert, we need to pop it off of the label vector before any
            // changes. This is because a label added with "vkCmdInsertDebugUtilsLabelEXT" is only a
            // temporary location that exists until the next operation occurs.  In this case, a
            // "vkCmdBeginDebugUtilsLabelEXT" has occurred erasing the inserted label.
            if (report_data->cmdBufLabelHasInsert) {
                report_data->cmdBufLabelHasInsert = false;
                label_iter->second.pop_back();
            }
            InsertLabelIntoLog(label_info, label_iter->second);
        }
    }
}

static inline void EndCmdDebugUtilsLabel(debug_report_data *report_data, VkCommandBuffer command_buffer) {
    auto label_iter = report_data->debugUtilsCmdBufLabels->find(command_buffer);
    if (label_iter != report_data->debugUtilsCmdBufLabels->end()) {
        // If the last thing was a label insert, we need to pop it off of the label vector before any
        // changes. This is because a label added with "vkCmdInsertDebugUtilsLabelEXT" is only a
        // temporary location that exists until the next operation occurs.  In this case, a
        // "vkCmdEndDebugUtilsLabelEXT" has occurred erasing the inserted label.
        if (report_data->cmdBufLabelHasInsert) {
            report_data->cmdBufLabelHasInsert = false;
            label_iter->second.pop_back();
        }
        // Now pop the normal item
        label_iter->second.pop_back();
    }
}

static inline void InsertCmdDebugUtilsLabel(debug_report_data *report_data, VkCommandBuffer command_buffer,
                                            const VkDebugUtilsLabelEXT *label_info) {
    if (nullptr != label_info && nullptr != label_info->pLabelName) {
        auto label_iter = report_data->debugUtilsCmdBufLabels->find(command_buffer);
        if (label_iter == report_data->debugUtilsCmdBufLabels->end()) {
            std::vector<LoggingLabelData> new_cmdbuf_labels;
            InsertLabelIntoLog(label_info, new_cmdbuf_labels);
            report_data->debugUtilsCmdBufLabels->insert({command_buffer, new_cmdbuf_labels});
        } else {
            // If the last thing was a label insert, we need to pop it off of the label vector before any
            // changes. This is because a label added with "vkCmdInsertDebugUtilsLabelEXT" is only a
            // temporary location that exists until the next operation occurs.  In this case, a new
            // "vkCmdInsertDebugUtilsLabelEXT" has occurred erasing the previous inserted label.
            if (report_data->cmdBufLabelHasInsert) {
                label_iter->second.pop_back();
            }
            // Insert this new label and mark it as one that has been "inserted" so we can remove it on
            // the next command buffer label operation.
            InsertLabelIntoLog(label_info, label_iter->second);
            report_data->cmdBufLabelHasInsert = true;
        }
    }
}

#endif  // LAYER_LOGGING_H
