/* 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.emplace(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.emplace(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;
    }

} 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
