/* Copyright (c) 2015-2019 The Khronos Group Inc.
 * Copyright (c) 2015-2019 Valve Corporation
 * Copyright (c) 2015-2019 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>
 * Author: Dave Houlton <daveh@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_loader_platform.h"
#include "vulkan/vk_layer.h"
#include "vk_object_types.h"
#include "vk_validation_error_messages.h"
#include "vk_layer_dispatch_table.h"
#include <mutex>
#include <signal.h>
#include <cinttypes>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <unordered_map>
#include <vector>
#include <sstream>
#include <string>

// Suppress unused warning on Linux
#if defined(__GNUC__)
#define DECORATE_UNUSED __attribute__((unused))
#else
#define DECORATE_UNUSED
#endif

#if defined __ANDROID__
#include <android/log.h>
#define LOGCONSOLE(...) ((void)__android_log_print(ANDROID_LOG_INFO, "VALIDATION", __VA_ARGS__))
#else
#define LOGCONSOLE(...)      \
    {                        \
        printf(__VA_ARGS__); \
        printf("\n");        \
    }
#endif

static const char DECORATE_UNUSED *kVUIDUndefined = "VUID_Undefined";

#undef DECORATE_UNUSED

// 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{nullptr};
    VkLayerDbgFunctionNode *default_debug_callback_list{nullptr};
    VkDebugUtilsMessageSeverityFlagsEXT active_severities{0};
    VkDebugUtilsMessageTypeFlagsEXT active_types{0};
    bool g_DEBUG_REPORT{false};
    bool g_DEBUG_UTILS{false};
    bool queueLabelHasInsert{false};
    bool cmdBufLabelHasInsert{false};
    std::unordered_map<uint64_t, std::string> debugObjectNameMap;
    std::unordered_map<uint64_t, std::string> debugUtilsObjectNameMap;
    std::unordered_map<VkQueue, std::vector<LoggingLabelData>> debugUtilsQueueLabels;
    std::unordered_map<VkCommandBuffer, std::vector<LoggingLabelData>> debugUtilsCmdBufLabels;
    // This mutex is defined as mutable since the normal usage for a debug report object is as 'const'. The mutable keyword allows
    // the layers to continue this pattern, but also allows them to use/change this specific member for synchronization purposes.
    mutable std::mutex debug_report_mutex;

    void DebugReportSetUtilsObjectName(const VkDebugUtilsObjectNameInfoEXT *pNameInfo) {
        std::unique_lock<std::mutex> lock(debug_report_mutex);
        if (pNameInfo->pObjectName) {
            debugUtilsObjectNameMap[pNameInfo->objectHandle] = pNameInfo->pObjectName;
        } else {
            debugUtilsObjectNameMap.erase(pNameInfo->objectHandle);
        }
    }

    void DebugReportSetMarkerObjectName(const VkDebugMarkerObjectNameInfoEXT *pNameInfo) {
        std::unique_lock<std::mutex> lock(debug_report_mutex);
        if (pNameInfo->pObjectName) {
            debugObjectNameMap[pNameInfo->object] = pNameInfo->pObjectName;
        } else {
            debugObjectNameMap.erase(pNameInfo->object);
        }
    }

    std::string DebugReportGetUtilsObjectName(const uint64_t object) const {
        std::string label = "";
        const auto utils_name_iter = debugUtilsObjectNameMap.find(object);
        if (utils_name_iter != debugUtilsObjectNameMap.end()) {
            label = utils_name_iter->second;
        }
        return label;
    }

    std::string DebugReportGetMarkerObjectName(const uint64_t object) const {
        std::string label = "";
        const auto marker_name_iter = debugObjectNameMap.find(object);
        if (marker_name_iter != debugObjectNameMap.end()) {
            label = marker_name_iter->second;
        }
        return label;
    }

    template <typename HANDLE_T>
    std::string FormatHandle(HANDLE_T *h) const {
        return FormatHandle(HandleToUint64(h));
    }

    std::string FormatHandle(uint64_t h) const {
        char uint64_string[64];
        sprintf(uint64_string, "0x%" PRIxLEAST64, h);
        std::string ret = uint64_string;

        std::string name = DebugReportGetUtilsObjectName(h);
        if (name.empty()) {
            name = DebugReportGetMarkerObjectName(h);
        }
        if (!name.empty()) {
            ret.append("[");
            ret.append(name);
            ret.append("]");
        }
        return ret;
    }

} 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) {
    *da_severity = 0;
    *da_type = 0;
    // If it's explicitly listed as a performance warning, treat it as a performance message.
    // Otherwise, treat it as a validation issue.
    if ((dr_flags & VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT) != 0) {
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
    }
    if ((dr_flags & VK_DEBUG_REPORT_DEBUG_BIT_EXT) != 0) {
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT;
    }
    if ((dr_flags & VK_DEBUG_REPORT_INFORMATION_BIT_EXT) != 0) {
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
    }
    if ((dr_flags & VK_DEBUG_REPORT_WARNING_BIT_EXT) != 0) {
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
    }
    if ((dr_flags & VK_DEBUG_REPORT_ERROR_BIT_EXT) != 0) {
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
        *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, const char *layer_prefix, const char *message,
                                 const char *text_vuid);

// 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 = nullptr;
    bool matched = false;
    VkFlags local_severities = 0;
    VkFlags local_types = 0;

    while (cur_callback) {
        if (cur_callback->is_messenger) {
            // If it's actually a messenger, then set it up for deletion.
            if (cur_callback->messenger.messenger == messenger) {
                matched = true;
                if (*list_head == cur_callback) {
                    *list_head = cur_callback->pNext;
                } else {
                    assert(nullptr != prev_callback);
                    prev_callback->pNext = 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, "DebugUtilsMessenger",
                              "Destroyed messenger\n", kVUIDUndefined);
            } else {
                // If it's not the one we're looking for, just keep the types/severities
                local_severities |= cur_callback->messenger.messageSeverity;
                local_types |= cur_callback->messenger.messageType;
            }
        } else {
            // If it's not a messenger, just keep the types/severities
            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;
        }
        if (matched) {
            free(cur_callback);
            matched = false;
            // Intentionally keep the last prev_callback, but select the proper cur_callback
            if (nullptr != prev_callback) {
                cur_callback = prev_callback->pNext;
            } else {
                cur_callback = *list_head;
            }
        } else {
            prev_callback = cur_callback;
            cur_callback = cur_callback->pNext;
        }
    }
    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 = nullptr;
    bool matched = false;
    VkFlags local_severities = 0;
    VkFlags local_types = 0;

    while (cur_callback) {
        if (!cur_callback->is_messenger) {
            // If it's actually a callback, then set it up for deletion.
            if (cur_callback->report.msgCallback == callback) {
                matched = true;
                if (*list_head == cur_callback) {
                    *list_head = cur_callback->pNext;
                } else {
                    assert(nullptr != prev_callback);
                    prev_callback->pNext = 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, "DebugReport",
                              "Destroyed callback\n", kVUIDUndefined);
            } else {
                // If it's not the one we're looking for, just keep the types/severities
                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;
            }
        } else {
            // If it's not a callback, just keep the types/severities
            local_severities |= cur_callback->messenger.messageSeverity;
            local_types |= cur_callback->messenger.messageType;
        }
        if (matched) {
            free(cur_callback);
            matched = false;
            // Intentionally keep the last prev_callback, but select the proper cur_callback
            if (nullptr != prev_callback) {
                cur_callback = prev_callback->pNext;
            } else {
                cur_callback = *list_head;
            }
        } else {
            prev_callback = cur_callback;
            cur_callback = cur_callback->pNext;
        }
    }
    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, "DebugReport",
                          "Debug Report callbacks not removed before DestroyInstance", kVUIDUndefined);
        } 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, "Messenger",
                          "Debug messengers not removed before DestroyInstance", kVUIDUndefined);
        }
        free(current_callback);
        current_callback = prev_callback;
    }
    *list_head = NULL;
}

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, 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 = 0;  // deprecated, validation layers use only the pMessageIdName
    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
        std::string label = debug_data->DebugReportGetUtilsObjectName(src_object);
        if (label.empty()) {
            label = debug_data->DebugReportGetMarkerObjectName(src_object);
        }
        if (!label.empty()) {
            object_name_info.pObjectName = label.c_str();
            oss << " (Name = " << label << " : 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, 0, 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)) {
            std::string messenger_label = debug_data->DebugReportGetUtilsObjectName(object_name_info.objectHandle);
            if (!messenger_label.empty()) {
                object_name_info.pObjectName = messenger_label.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) {
            VkDebugReportObjectTypeEXT object_type = convertCoreObjectToDebugReportObject(callback_data->pObjects[0].objectType);
            std::string marker_label = debug_data->DebugReportGetMarkerObjectName(object_name_info.objectHandle);
            if (marker_label.empty()) {
                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 = " + marker_label;
                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 = new debug_report_data;
    for (uint32_t i = 0; i < extension_count; i++) {
        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;
        }
    }
    return debug_data;
}

static inline void layer_debug_utils_destroy_instance(debug_report_data *debug_data) {
    if (debug_data) {
        std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
        RemoveAllMessageCallbacks(debug_data, &debug_data->default_debug_callback_list);
        RemoveAllMessageCallbacks(debug_data, &debug_data->debug_callback_list);
        lock.unlock();
        delete (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) {
    std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
    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) {
    std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
    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) {
    std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
    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) {
    std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
    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,
                  "DebugReport", "Added callback", kVUIDUndefined);
    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);  // Set the storage length long enough to hold the output + null
    formatted.resize(reserve);       // Set the *logical* length to be what vsprintf will write
    va_start(argptr, fmt);
    int result = vsnprintf((char *)formatted.data(), formatted.capacity(), fmt, argptr);
    va_end(argptr);
    assert(result == reserve);
    assert((formatted.size() == strlen(formatted.c_str())));
    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, 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, std::string vuid_text, const char *format, ...) {
    if (!debug_data) return false;
    std::unique_lock<std::mutex> lock(debug_data->debug_report_mutex);
    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 ? str : "Allocation failure");

    // Append the spec error text to the error message, unless it's an UNASSIGNED or UNDEFINED vuid
    if ((vuid_text.find("UNASSIGNED-") == std::string::npos) && (vuid_text.find(kVUIDUndefined) == std::string::npos)) {
        // Linear search makes no assumptions about the layout of the string table
        // This is not fast, but it does not need to be at this point in the error reporting path
        uint32_t num_vuids = sizeof(vuid_spec_text) / sizeof(vuid_spec_text_pair);
        const char *spec_text = nullptr;
        for (uint32_t i = 0; i < num_vuids; i++) {
            if (0 == strcmp(vuid_text.c_str(), vuid_spec_text[i].vuid)) {
                spec_text = vuid_spec_text[i].spec_text;
                break;
            }
        }

        if (nullptr == spec_text) {
            // If this happens, you've hit a VUID string that isn't defined in the spec's json file
            // Try running 'vk_validation_stats -c' to look for invalid VUID strings in the repo code
            assert(0);
        } else {
            str_plus_spec_text += " The Vulkan spec states: ";
            str_plus_spec_text += spec_text;
        }
    }

    // Append layer prefix with VUID string, pass in recovered legacy numerical VUID
    bool result = debug_log_msg(debug_data, msg_flags, object_type, src_object, 0, "Validation", str_plus_spec_text.c_str(),
                                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) {
    std::ostringstream msg_buffer;
    char msg_flag_string[30];

    PrintMessageFlags(msg_flags, msg_flag_string);

    msg_buffer << layer_prefix << "(" << msg_flag_string << "): msg_code: " << msg_code << ": " << message << "\n";
    const std::string tmp = msg_buffer.str();
    const char *cstr = tmp.c_str();

    fprintf((FILE *)user_data, "%s", cstr);
    fflush((FILE *)user_data);

#if defined __ANDROID__
    LOGCONSOLE("%s", cstr);
#endif

    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) {
    std::ostringstream msg_buffer;
    char msg_severity[30];
    char msg_type[30];

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

    msg_buffer << callback_data->pMessageIdName << "(" << msg_severity << " / " << msg_type
               << "): msgNum: " << callback_data->messageIdNumber << " - " << callback_data->pMessage << "\n";
    msg_buffer << "    Objects: " << callback_data->objectCount << "\n";
    for (uint32_t obj = 0; obj < callback_data->objectCount; ++obj) {
        msg_buffer << "        [" << obj << "] " << std::hex << std::showbase
                   << HandleToUint64(callback_data->pObjects[obj].objectHandle) << ", type: " << std::dec << std::noshowbase
                   << callback_data->pObjects[obj].objectType
                   << ", name: " << (callback_data->pObjects[obj].pObjectName ? callback_data->pObjects[obj].pObjectName : "NULL")
                   << "\n";
    }
    const std::string tmp = msg_buffer.str();
    const char *cstr = tmp.c_str();
    fprintf((FILE *)user_data, "%s", cstr);
    fflush((FILE *)user_data);

#if defined __ANDROID__
    LOGCONSOLE("%s", cstr);
#endif

    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
    std::ostringstream msg_buffer;
    char msg_severity[30];
    char msg_type[30];

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

    msg_buffer << callback_data->pMessageIdName << "(" << msg_severity << " / " << msg_type
               << "): msgNum: " << callback_data->messageIdNumber << " - " << callback_data->pMessage << "\n";
    msg_buffer << "    Objects: " << callback_data->objectCount << "\n";

    for (uint32_t obj = 0; obj < callback_data->objectCount; ++obj) {
        msg_buffer << "       [" << obj << "]  " << std::hex << std::showbase
                   << HandleToUint64(callback_data->pObjects[obj].objectHandle) << ", type: " << std::dec << std::noshowbase
                   << callback_data->pObjects[obj].objectType
                   << ", name: " << (callback_data->pObjects[obj].pObjectName ? callback_data->pObjects[obj].pObjectName : "NULL")
                   << "\n";
    }
    const std::string tmp = msg_buffer.str();
    const char *cstr = tmp.c_str();
    OutputDebugString(cstr);
#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) {
    std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
    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) {
    std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
    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) {
    std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
    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) {
    std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
    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) {
    std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
    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();
        }
        // Guard against unbalanced markers.
        if (label_iter->second.size() > 0) {
            // 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) {
    std::unique_lock<std::mutex> lock(report_data->debug_report_mutex);
    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
