/* Copyright (c) 2015-2021 The Khronos Group Inc.
 * Copyright (c) 2015-2021 Valve Corporation
 * Copyright (c) 2015-2021 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 <cinttypes>
#include <signal.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>

#include <algorithm>
#include <array>
#include <memory>
#include <mutex>
#include <sstream>
#include <string>
#include <vector>
#include <utility>
#include <cstring>

#include "vk_typemap_helper.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_enum_string_helper.h"
#include "cast_utils.h"
#include "vk_validation_error_messages.h"
#include "vk_layer_dispatch_table.h"
#include "vk_safe_struct.h"
#include "xxhash.h"

// 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__))
static const char DECORATE_UNUSED *kForceDefaultCallbackKey = "debug.vvl.forcelayerlog";
#else
#define LOGCONSOLE(...)      \
    {                        \
        printf(__VA_ARGS__); \
        printf("\n");        \
    }
#endif

static const char DECORATE_UNUSED *kVUIDUndefined = "VUID_Undefined";

#undef DECORATE_UNUSED

typedef enum DebugCallbackStatusBits {
    DEBUG_CALLBACK_UTILS = 0x00000001,     // This struct describes a VK_EXT_debug_utils callback
    DEBUG_CALLBACK_DEFAULT = 0x00000002,   // An internally created callback, used if no user-defined callbacks are registered
    DEBUG_CALLBACK_INSTANCE = 0x00000004,  // An internally created temporary instance callback
} DebugCallbackStatusBits;
typedef VkFlags DebugCallbackStatusFlags;

struct LogObjectList {
    small_vector<VulkanTypedHandle, 4, uint32_t> object_list;

    template <typename HANDLE_T>
    void add(HANDLE_T object) {
        object_list.emplace_back(object, ConvertCoreObjectToVulkanObject(VkHandleInfo<HANDLE_T>::kVkObjectType));
    }

    void add(VulkanTypedHandle typed_handle) { object_list.emplace_back(typed_handle); }

    template <typename HANDLE_T>
    LogObjectList(HANDLE_T object) {
        add(object);
    }

    LogObjectList(){};
};

typedef struct VkLayerDbgFunctionState {
    DebugCallbackStatusFlags callback_status;

    // Debug report related information
    VkDebugReportCallbackEXT debug_report_callback_object;
    PFN_vkDebugReportCallbackEXT debug_report_callback_function_ptr;
    VkFlags debug_report_msg_flags;

    // Debug utils related information
    VkDebugUtilsMessengerEXT debug_utils_callback_object;
    VkDebugUtilsMessageSeverityFlagsEXT debug_utils_msg_flags;
    VkDebugUtilsMessageTypeFlagsEXT debug_utils_msg_type;
    PFN_vkDebugUtilsMessengerCallbackEXT debug_utils_callback_function_ptr;

    void *pUserData;

    bool IsUtils() const { return ((callback_status & DEBUG_CALLBACK_UTILS) != 0); }
    bool IsDefault() const { return ((callback_status & DEBUG_CALLBACK_DEFAULT) != 0); }
    bool IsInstance() const { return ((callback_status & DEBUG_CALLBACK_INSTANCE) != 0); }
} VkLayerDbgFunctionState;

// 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 CastToUint64<HANDLE_T>(h);
}

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

// Data we store per label for logging
struct LoggingLabel {
    std::string name;
    std::array<float, 4> color;

    void Reset() { *this = LoggingLabel(); }
    bool Empty() const { return name.empty(); }

    VkDebugUtilsLabelEXT Export() const {
        auto out = LvlInitStruct<VkDebugUtilsLabelEXT>();
        out.pLabelName = name.c_str();
        std::copy(color.cbegin(), color.cend(), out.color);
        return out;
    };

    LoggingLabel() : name(), color({{0.f, 0.f, 0.f, 0.f}}) {}
    LoggingLabel(const VkDebugUtilsLabelEXT *label_info) {
        if (label_info && label_info->pLabelName) {
            name = label_info->pLabelName;
            std::copy_n(std::begin(label_info->color), 4, color.begin());
        } else {
            Reset();
        }
    }

    LoggingLabel(const LoggingLabel &) = default;
    LoggingLabel &operator=(const LoggingLabel &) = default;
    LoggingLabel &operator=(LoggingLabel &&) = default;
    LoggingLabel(LoggingLabel &&) = default;

    template <typename Name, typename Vec>
    LoggingLabel(Name &&name_, Vec &&vec_) : name(std::forward<Name>(name_)), color(std::forward<Vec>(vec_)) {}
};

struct LoggingLabelState {
    std::vector<LoggingLabel> labels;
    LoggingLabel insert_label;

    // Export the labels, but in reverse order since we want the most recent at the top.
    std::vector<VkDebugUtilsLabelEXT> Export() const {
        size_t count = labels.size() + (insert_label.Empty() ? 0 : 1);
        std::vector<VkDebugUtilsLabelEXT> out(count);

        if (!count) return out;

        size_t index = count - 1;
        if (!insert_label.Empty()) {
            out[index--] = insert_label.Export();
        }
        for (const auto &label : labels) {
            out[index--] = label.Export();
        }
        return out;
    }
};

typedef struct _debug_report_data {
    std::vector<VkLayerDbgFunctionState> debug_callback_list;
    VkDebugUtilsMessageSeverityFlagsEXT active_severities{0};
    VkDebugUtilsMessageTypeFlagsEXT active_types{0};
    bool queueLabelHasInsert{false};
    bool cmdBufLabelHasInsert{false};
    layer_data::unordered_map<uint64_t, std::string> debugObjectNameMap;
    layer_data::unordered_map<uint64_t, std::string> debugUtilsObjectNameMap;
    layer_data::unordered_map<VkQueue, std::unique_ptr<LoggingLabelState>> debugUtilsQueueLabels;
    layer_data::unordered_map<VkCommandBuffer, std::unique_ptr<LoggingLabelState>> debugUtilsCmdBufLabels;
    std::vector<uint32_t> filter_message_ids{};
    // 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_output_mutex;
    int32_t duplicate_message_limit = 0;
    mutable layer_data::unordered_map<uint32_t, int32_t> duplicate_message_count_map{};
    const void *instance_pnext_chain{};
    bool forceDefaultLogCallback{false};

    void DebugReportSetUtilsObjectName(const VkDebugUtilsObjectNameInfoEXT *pNameInfo) {
        std::unique_lock<std::mutex> lock(debug_output_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_output_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;
    }

    std::string FormatHandle(const char *handle_type_name, uint64_t handle) const {
        std::string handle_name = DebugReportGetUtilsObjectName(handle);
        if (handle_name.empty()) {
            handle_name = DebugReportGetMarkerObjectName(handle);
        }

        std::ostringstream str;
        str << handle_type_name << " 0x" << std::hex << handle << "[" << handle_name.c_str() << "]";
        return str.str();
    }

    std::string FormatHandle(const VulkanTypedHandle &handle) const {
        return FormatHandle(object_string[handle.type], handle.handle);
    }

    template <typename HANDLE_T>
    std::string FormatHandle(HANDLE_T handle) const {
        return FormatHandle(VkHandleInfo<HANDLE_T>::Typename(), HandleToUint64(handle));
    }

} 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 & kPerformanceWarningBit) != 0) {
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT;
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
    }
    if ((dr_flags & kDebugBit) != 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 & kInformationBit) != 0) {
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT;
    }
    if ((dr_flags & kWarningBit) != 0) {
        *da_type |= VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT;
        *da_severity |= VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT;
    }
    if ((dr_flags & kErrorBit) != 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, const LogObjectList &objects,
                                 const char *layer_prefix, const char *message, const char *text_vuid);

static void SetDebugUtilsSeverityFlags(std::vector<VkLayerDbgFunctionState> &callbacks, debug_report_data *debug_data) {
    // For all callback in list, return their complete set of severities and modes
    for (const auto &item : callbacks) {
        if (item.IsUtils()) {
            debug_data->active_severities |= item.debug_utils_msg_flags;
            debug_data->active_types |= item.debug_utils_msg_type;
        } else {
            VkFlags severities = 0;
            VkFlags types = 0;
            DebugReportFlagsToAnnotFlags(item.debug_report_msg_flags, true, &severities, &types);
            debug_data->active_severities |= severities;
            debug_data->active_types |= types;
        }
    }
}

static inline void RemoveDebugUtilsCallback(debug_report_data *debug_data, std::vector<VkLayerDbgFunctionState> &callbacks,
                                            uint64_t callback) {
    auto item = callbacks.begin();
    for (item = callbacks.begin(); item != callbacks.end(); item++) {
        if (item->IsUtils()) {
            if (item->debug_utils_callback_object == CastToHandle<VkDebugUtilsMessengerEXT>(callback)) break;
        } else {
            if (item->debug_report_callback_object == CastToHandle<VkDebugReportCallbackEXT>(callback)) break;
        }
    }
    if (item != callbacks.end()) {
        callbacks.erase(item);
    }
    SetDebugUtilsSeverityFlags(callbacks, debug_data);
}

// Deletes all debug callback function structs
static inline void RemoveAllMessageCallbacks(debug_report_data *debug_data, std::vector<VkLayerDbgFunctionState> &callbacks) {
    callbacks.clear();
}

// Returns TRUE if the number of times this message has been logged is over the set limit
static inline bool UpdateLogMsgCounts(const debug_report_data *debug_data, int32_t vuid_hash) {
    auto vuid_count_it = debug_data->duplicate_message_count_map.find(vuid_hash);
    if (vuid_count_it == debug_data->duplicate_message_count_map.end()) {
        debug_data->duplicate_message_count_map.emplace(vuid_hash, 1);
        return false;
    } else {
        if (vuid_count_it->second >= debug_data->duplicate_message_limit) {
            return true;
        } else {
            vuid_count_it->second++;
            return false;
        }
    }
}

static inline bool debug_log_msg(const debug_report_data *debug_data, VkFlags msg_flags, const LogObjectList &objects,
                                 const char *layer_prefix, const char *message, const char *text_vuid) {
    bool bail = false;
    std::vector<VkDebugUtilsLabelEXT> queue_labels;
    std::vector<VkDebugUtilsLabelEXT> cmd_buf_labels;

    // Convert the info to the VK_EXT_debug_utils format
    VkDebugUtilsMessageTypeFlagsEXT types;
    VkDebugUtilsMessageSeverityFlagsEXT severity;
    DebugReportFlagsToAnnotFlags(msg_flags, true, &severity, &types);

    std::vector<VkDebugUtilsObjectNameInfoEXT> object_name_info;
    object_name_info.resize(objects.object_list.size());
    for (uint32_t i = 0; i < objects.object_list.size(); i++) {
        object_name_info[i] = LvlInitStruct<VkDebugUtilsObjectNameInfoEXT>();
        object_name_info[i].objectType = ConvertVulkanObjectToCoreObject(objects.object_list[i].type);
        object_name_info[i].objectHandle = objects.object_list[i].handle;
        object_name_info[i].pObjectName = NULL;

        std::string object_label = {};
        // Look for any debug utils or marker names to use for this object
        object_label = debug_data->DebugReportGetUtilsObjectName(objects.object_list[i].handle);
        if (object_label.empty()) {
            object_label = debug_data->DebugReportGetMarkerObjectName(objects.object_list[i].handle);
        }
        if (!object_label.empty()) {
            char *local_obj_name = new char[object_label.length() + 1];
            std::strcpy(local_obj_name, object_label.c_str());
            object_name_info[i].pObjectName = local_obj_name;
        }

        // If this is a queue, add any queue labels to the callback data.
        if (VK_OBJECT_TYPE_QUEUE == object_name_info[i].objectType) {
            auto label_iter = debug_data->debugUtilsQueueLabels.find(reinterpret_cast<VkQueue>(object_name_info[i].objectHandle));
            if (label_iter != debug_data->debugUtilsQueueLabels.end()) {
                auto found_queue_labels = label_iter->second->Export();
                queue_labels.insert(queue_labels.end(), found_queue_labels.begin(), found_queue_labels.end());
            }
            // 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[i].objectType) {
            auto label_iter =
                debug_data->debugUtilsCmdBufLabels.find(reinterpret_cast<VkCommandBuffer>(object_name_info[i].objectHandle));
            if (label_iter != debug_data->debugUtilsCmdBufLabels.end()) {
                auto found_cmd_buf_labels = label_iter->second->Export();
                cmd_buf_labels.insert(cmd_buf_labels.end(), found_cmd_buf_labels.begin(), found_cmd_buf_labels.end());
            }
        }
    }

    int32_t location = 0;
    if (text_vuid != nullptr) {
        // Hash for vuid text
        location = XXH32(text_vuid, strlen(text_vuid), 8);
    }

    auto callback_data = LvlInitStruct<VkDebugUtilsMessengerCallbackDataEXT>();
    callback_data.flags = 0;
    callback_data.pMessageIdName = text_vuid;
    callback_data.messageIdNumber = static_cast<int32_t>(location);
    callback_data.pMessage = NULL;
    callback_data.queueLabelCount = static_cast<uint32_t>(queue_labels.size());
    callback_data.pQueueLabels = queue_labels.empty() ? nullptr : queue_labels.data();
    callback_data.cmdBufLabelCount = static_cast<uint32_t>(cmd_buf_labels.size());
    callback_data.pCmdBufLabels = cmd_buf_labels.empty() ? nullptr : cmd_buf_labels.data();
    callback_data.objectCount = static_cast<uint32_t>(object_name_info.size());
    callback_data.pObjects = object_name_info.data();

    std::ostringstream oss;
    if (msg_flags & kErrorBit) {
        oss << "Validation Error: ";
    } else if (msg_flags & kWarningBit) {
        oss << "Validation Warning: ";
    } else if (msg_flags & kPerformanceWarningBit) {
        oss << "Validation Performance Warning: ";
    } else if (msg_flags & kInformationBit) {
        oss << "Validation Information: ";
    } else if (msg_flags & kDebugBit) {
        oss << "DEBUG: ";
    }
    if (text_vuid != nullptr) {
        oss << "[ " << text_vuid << " ] ";
    }
    uint32_t index = 0;
    for (const auto &src_object : object_name_info) {
        if (0 != src_object.objectHandle) {
            oss << "Object " << index++ << ": handle = 0x" << std::hex << src_object.objectHandle;
            if (src_object.pObjectName) {
                oss << ", name = " << src_object.pObjectName << ", type = ";
            } else {
                oss << ", type = ";
            }
            oss << string_VkObjectType(src_object.objectType) << "; ";
        } else {
            oss << "Object " << index++ << ": VK_NULL_HANDLE, type = " << string_VkObjectType(src_object.objectType) << "; ";
        }
    }
    oss << "| MessageID = 0x" << std::hex << location << " | " << message;
    std::string composite = oss.str();

    const auto callback_list = &debug_data->debug_callback_list;
    // We only output to default callbacks if there are no non-default callbacks
    bool use_default_callbacks = true;
    for (const auto &current_callback : *callback_list) {
        use_default_callbacks &= current_callback.IsDefault();
    }

#if defined __ANDROID__
    if (debug_data->forceDefaultLogCallback) {
        use_default_callbacks = true;
    }
#endif

    for (const auto &current_callback : *callback_list) {
        // Skip callback if it's a default callback and there are non-default callbacks present
        if (current_callback.IsDefault() && !use_default_callbacks) continue;

        // VK_EXT_debug_utils callback
        if (current_callback.IsUtils() && (current_callback.debug_utils_msg_flags & severity) &&
            (current_callback.debug_utils_msg_type & types)) {
            callback_data.pMessage = composite.c_str();
            if (current_callback.debug_utils_callback_function_ptr(static_cast<VkDebugUtilsMessageSeverityFlagBitsEXT>(severity),
                                                                   types, &callback_data, current_callback.pUserData)) {
                bail = true;
            }
        } else if (!current_callback.IsUtils() && (current_callback.debug_report_msg_flags & msg_flags)) {
            // VK_EXT_debug_report callback (deprecated)
            if (current_callback.debug_report_callback_function_ptr(
                    msg_flags, convertCoreObjectToDebugReportObject(object_name_info[0].objectType),
                    object_name_info[0].objectHandle, location, 0, layer_prefix, composite.c_str(), current_callback.pUserData)) {
                bail = true;
            }
        }
    }
    return bail;
}

static inline VkDebugReportFlagsEXT DebugAnnotFlagsToReportFlags(VkDebugUtilsMessageSeverityFlagBitsEXT da_severity,
                                                                 VkDebugUtilsMessageTypeFlagsEXT da_type) {
    if (da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) return VK_DEBUG_REPORT_ERROR_BIT_EXT;
    if (da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT) {
        if (da_type & VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT)
            return VK_DEBUG_REPORT_PERFORMANCE_WARNING_BIT_EXT;
        else
            return VK_DEBUG_REPORT_WARNING_BIT_EXT;
    }
    if (da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) return VK_DEBUG_REPORT_INFORMATION_BIT_EXT;
    if (da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) return VK_DEBUG_REPORT_DEBUG_BIT_EXT;

    return 0;
}

static inline LogMessageTypeFlags DebugAnnotFlagsToMsgTypeFlags(VkDebugUtilsMessageSeverityFlagBitsEXT da_severity,
                                                                VkDebugUtilsMessageTypeFlagsEXT da_type) {
    LogMessageTypeFlags msg_type_flags = 0;
    if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT) != 0) {
        msg_type_flags |= kErrorBit;
    } 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) {
            msg_type_flags |= kPerformanceWarningBit;
        } else {
            msg_type_flags |= kWarningBit;
        }
    } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT) != 0) {
        msg_type_flags |= kInformationBit;
    } else if ((da_severity & VK_DEBUG_UTILS_MESSAGE_SEVERITY_VERBOSE_BIT_EXT) != 0) {
        msg_type_flags |= kDebugBit;
    }
    return msg_type_flags;
}

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_output_mutex);
        RemoveAllMessageCallbacks(debug_data, debug_data->debug_callback_list);
        lock.unlock();
        delete (debug_data);
    }
}

template <typename T>
static inline void layer_destroy_callback(debug_report_data *debug_data, T callback, const VkAllocationCallbacks *allocator) {
    std::unique_lock<std::mutex> lock(debug_data->debug_output_mutex);
    RemoveDebugUtilsCallback(debug_data, debug_data->debug_callback_list, CastToUint64(callback));
}

template <typename TCreateInfo, typename TCallback>
static inline void layer_create_callback(DebugCallbackStatusFlags callback_status, debug_report_data *debug_data,
                                         const TCreateInfo *create_info, const VkAllocationCallbacks *allocator,
                                         TCallback *callback) {
    std::unique_lock<std::mutex> lock(debug_data->debug_output_mutex);

    debug_data->debug_callback_list.emplace_back(VkLayerDbgFunctionState());
    auto &callback_state = debug_data->debug_callback_list.back();
    callback_state.callback_status = callback_status;
    callback_state.pUserData = create_info->pUserData;

    if (callback_state.IsUtils()) {
        auto utils_create_info = reinterpret_cast<const VkDebugUtilsMessengerCreateInfoEXT *>(create_info);
        auto utils_callback = reinterpret_cast<VkDebugUtilsMessengerEXT *>(callback);
        if (!(*utils_callback)) {
            // callback constructed default callbacks have no handle -- so use struct address as unique handle
            *utils_callback = reinterpret_cast<VkDebugUtilsMessengerEXT>(&callback_state);
        }
        callback_state.debug_utils_callback_object = *utils_callback;
        callback_state.debug_utils_callback_function_ptr = utils_create_info->pfnUserCallback;
        callback_state.debug_utils_msg_flags = utils_create_info->messageSeverity;
        callback_state.debug_utils_msg_type = utils_create_info->messageType;
    } else {  // Debug report callback
        auto report_create_info = reinterpret_cast<const VkDebugReportCallbackCreateInfoEXT *>(create_info);
        auto report_callback = reinterpret_cast<VkDebugReportCallbackEXT *>(callback);
        if (!(*report_callback)) {
            // Internally constructed default callbacks have no handle -- so use struct address as unique handle
            *report_callback = reinterpret_cast<VkDebugReportCallbackEXT>(&callback_state);
        }
        callback_state.debug_report_callback_object = *report_callback;
        callback_state.debug_report_callback_function_ptr = report_create_info->pfnCallback;
        callback_state.debug_report_msg_flags = report_create_info->flags;
    }

#if defined __ANDROID__
    // On Android, if the default callback system property is set, force the default callback to be printed
    std::string forceLayerLog = GetEnvironment(kForceDefaultCallbackKey);
    int forceDefaultCallback = atoi(forceLayerLog.c_str());
    if (forceDefaultCallback == 1) {
        debug_data->forceDefaultLogCallback = true;
    }
#endif

    SetDebugUtilsSeverityFlags(debug_data->debug_callback_list, debug_data);
}

static inline VkResult layer_create_messenger_callback(debug_report_data *debug_data, bool default_callback,
                                                       const VkDebugUtilsMessengerCreateInfoEXT *create_info,
                                                       const VkAllocationCallbacks *allocator,
                                                       VkDebugUtilsMessengerEXT *messenger) {
    layer_create_callback((DEBUG_CALLBACK_UTILS | (default_callback ? DEBUG_CALLBACK_DEFAULT : 0)), debug_data, create_info,
                          allocator, messenger);
    return VK_SUCCESS;
}

static inline VkResult layer_create_report_callback(debug_report_data *debug_data, bool default_callback,
                                                    const VkDebugReportCallbackCreateInfoEXT *create_info,
                                                    const VkAllocationCallbacks *allocator, VkDebugReportCallbackEXT *callback) {
    layer_create_callback((default_callback ? DEBUG_CALLBACK_DEFAULT : 0), debug_data, create_info, allocator, callback);
    return VK_SUCCESS;
}

static inline void ActivateInstanceDebugCallbacks(debug_report_data *debug_data) {
    auto current = debug_data->instance_pnext_chain;
    for (;;) {
        auto create_info = LvlFindInChain<VkDebugUtilsMessengerCreateInfoEXT>(current);
        if (!create_info) break;
        current = create_info->pNext;
        VkDebugUtilsMessengerEXT utils_callback{};
        layer_create_callback((DEBUG_CALLBACK_UTILS | DEBUG_CALLBACK_INSTANCE), debug_data, create_info, nullptr, &utils_callback);
    }
    for (;;) {
        auto create_info = LvlFindInChain<VkDebugReportCallbackCreateInfoEXT>(current);
        if (!create_info) break;
        current = create_info->pNext;
        VkDebugReportCallbackEXT report_callback{};
        layer_create_callback(DEBUG_CALLBACK_INSTANCE, debug_data, create_info, nullptr, &report_callback);
    }
}

static inline void DeactivateInstanceDebugCallbacks(debug_report_data *debug_data) {
    if (!LvlFindInChain<VkDebugUtilsMessengerCreateInfoEXT>(debug_data->instance_pnext_chain) &&
        !LvlFindInChain<VkDebugReportCallbackCreateInfoEXT>(debug_data->instance_pnext_chain))
        return;
    std::vector<VkDebugUtilsMessengerEXT> instance_utils_callback_handles{};
    std::vector<VkDebugReportCallbackEXT> instance_report_callback_handles{};
    for (const auto &item : debug_data->debug_callback_list) {
        if (item.IsInstance()) {
            if (item.IsUtils()) {
                instance_utils_callback_handles.push_back(item.debug_utils_callback_object);
            } else {
                instance_report_callback_handles.push_back(item.debug_report_callback_object);
            }
        }
    }
    for (const auto &item : instance_utils_callback_handles) {
        layer_destroy_callback(debug_data, item, nullptr);
    }
    for (const auto &item : instance_report_callback_handles) {
        layer_destroy_callback(debug_data, item, nullptr);
    }
}

#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

// helper for VUID based filtering. This needs to be separate so it can be called before incurring
// the cost of sprintf()-ing the err_msg needed by LogMsgLocked().
static inline bool LogMsgEnabled(const debug_report_data *debug_data, const std::string &vuid_text,
                                 VkDebugUtilsMessageSeverityFlagsEXT severity, VkDebugUtilsMessageTypeFlagsEXT type) {
    if (!(debug_data->active_severities & severity) || !(debug_data->active_types & type)) {
        return false;
    }
    // If message is in filter list, bail out very early
    uint32_t message_id = XXH32(vuid_text.c_str(), strlen(vuid_text.c_str()), 8);
    if (std::find(debug_data->filter_message_ids.begin(), debug_data->filter_message_ids.end(), message_id)
        != debug_data->filter_message_ids.end()) {
        return false;
    }
    if ((debug_data->duplicate_message_limit > 0) && UpdateLogMsgCounts(debug_data, static_cast<int32_t>(message_id))) {
        // Count for this particular message is over the limit, ignore it
        return false;
    }
    return true;
}

static inline bool LogMsgLocked(const debug_report_data *debug_data, VkFlags msg_flags, const LogObjectList &objects,
                                const std::string &vuid_text, char *err_msg) {
    std::string str_plus_spec_text(err_msg ? err_msg : "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) &&
        (vuid_text.rfind("SYNC-", 0) == 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;
        std::string spec_type;
        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;
                spec_type = vuid_spec_text[i].url_id;
                break;
            }
        }

        // Construct and append the specification text and link to the appropriate version of the spec
        if (nullptr != spec_text) {
            std::string spec_link = "https://www.khronos.org/registry/vulkan/specs/_MAGIC_KHRONOS_SPEC_TYPE_/html/vkspec.html";
#ifdef ANNOTATED_SPEC_LINK
            spec_link = ANNOTATED_SPEC_LINK;
#endif
            static std::string kAtToken = "_MAGIC_ANNOTATED_SPEC_TYPE_";
            static std::string kKtToken = "_MAGIC_KHRONOS_SPEC_TYPE_";
            static std::string kVeToken = "_MAGIC_VERSION_ID_";
            auto Replace = [](std::string &dest_string, const std::string &to_replace, const std::string &replace_with) {
                if (dest_string.find(to_replace) != std::string::npos) {
                    dest_string.replace(dest_string.find(to_replace), to_replace.size(), replace_with);
                }
            };

            str_plus_spec_text.append(" The Vulkan spec states: ");
            str_plus_spec_text.append(spec_text);
            if (0 == spec_type.compare("default")) {
                str_plus_spec_text.append(" (https://github.com/KhronosGroup/Vulkan-Docs/search?q=)");
            } else {
                str_plus_spec_text.append(" (");
                str_plus_spec_text.append(spec_link);
                std::string major_version = std::to_string(VK_VERSION_MAJOR(VK_HEADER_VERSION_COMPLETE));
                std::string minor_version = std::to_string(VK_VERSION_MINOR(VK_HEADER_VERSION_COMPLETE));
                std::string patch_version = std::to_string(VK_VERSION_PATCH(VK_HEADER_VERSION_COMPLETE));
                std::string header_version = major_version + "." + minor_version + "." + patch_version;
                std::string annotated_spec_type = major_version + "." + minor_version + "-extensions";
                Replace(str_plus_spec_text, kKtToken, spec_type);
                Replace(str_plus_spec_text, kAtToken, annotated_spec_type);
                Replace(str_plus_spec_text, kVeToken, header_version);
                str_plus_spec_text.append("#");  // CMake hates hashes
            }
            str_plus_spec_text.append(vuid_text);
            str_plus_spec_text.append(")");
        }
    }

    bool result = debug_log_msg(debug_data, msg_flags, objects, "Validation", str_plus_spec_text.c_str(), vuid_text.c_str());
    free(err_msg);
    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 MessengerBreakCallback(VkDebugUtilsMessageSeverityFlagBitsEXT message_severity,
                                                                    VkDebugUtilsMessageTypeFlagsEXT message_type,
                                                                    const VkDebugUtilsMessengerCallbackDataEXT *callback_data,
                                                                    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;
}

template <typename Map>
static LoggingLabelState *GetLoggingLabelState(Map *map, typename Map::key_type key, bool insert) {
    auto iter = map->find(key);
    LoggingLabelState *label_state = nullptr;
    if (iter == map->end()) {
        if (insert) {
            // Add a label state if not present
            auto inserted = map->emplace(key, std::unique_ptr<LoggingLabelState>(new LoggingLabelState()));
            assert(inserted.second);
            iter = inserted.first;
            label_state = iter->second.get();
        }
    } else {
        label_state = iter->second.get();
    }
    return label_state;
}

static inline void BeginQueueDebugUtilsLabel(debug_report_data *report_data, VkQueue queue,
                                             const VkDebugUtilsLabelEXT *label_info) {
    std::unique_lock<std::mutex> lock(report_data->debug_output_mutex);
    if (nullptr != label_info && nullptr != label_info->pLabelName) {
        auto *label_state = GetLoggingLabelState(&report_data->debugUtilsQueueLabels, queue, /* insert */ true);
        assert(label_state);
        label_state->labels.emplace_back(label_info);

        // TODO: Determine if this is the correct semantics for insert label vs. begin/end, perserving existing semantics for now
        label_state->insert_label.Reset();
    }
}

static inline void EndQueueDebugUtilsLabel(debug_report_data *report_data, VkQueue queue) {
    std::unique_lock<std::mutex> lock(report_data->debug_output_mutex);
    auto *label_state = GetLoggingLabelState(&report_data->debugUtilsQueueLabels, queue, /* insert */ false);
    if (label_state) {
        // Pop the normal item
        if (!label_state->labels.empty()) {
            label_state->labels.pop_back();
        }

        // TODO: Determine if this is the correct semantics for insert label vs. begin/end, perserving existing semantics for now
        label_state->insert_label.Reset();
    }
}

static inline void InsertQueueDebugUtilsLabel(debug_report_data *report_data, VkQueue queue,
                                              const VkDebugUtilsLabelEXT *label_info) {
    std::unique_lock<std::mutex> lock(report_data->debug_output_mutex);
    auto *label_state = GetLoggingLabelState(&report_data->debugUtilsQueueLabels, queue, /* insert */ true);

    // TODO: Determine if this is the correct semantics for insert label vs. begin/end, perserving existing semantics for now
    label_state->insert_label = LoggingLabel(label_info);
}

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_output_mutex);
    if (nullptr != label_info && nullptr != label_info->pLabelName) {
        auto *label_state = GetLoggingLabelState(&report_data->debugUtilsCmdBufLabels, command_buffer, /* insert */ true);
        assert(label_state);
        label_state->labels.push_back(LoggingLabel(label_info));

        // TODO: Determine if this is the correct semantics for insert label vs. begin/end, perserving existing semantics for now
        label_state->insert_label.Reset();
    }
}

static inline void EndCmdDebugUtilsLabel(debug_report_data *report_data, VkCommandBuffer command_buffer) {
    std::unique_lock<std::mutex> lock(report_data->debug_output_mutex);
    auto *label_state = GetLoggingLabelState(&report_data->debugUtilsCmdBufLabels, command_buffer, /* insert */ false);
    if (label_state) {
        // Pop the normal item
        if (!label_state->labels.empty()) {
            label_state->labels.pop_back();
        }

        // TODO: Determine if this is the correct semantics for insert label vs. begin/end, perserving existing semantics for now
        label_state->insert_label.Reset();
    }
}

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_output_mutex);
    auto *label_state = GetLoggingLabelState(&report_data->debugUtilsCmdBufLabels, command_buffer, /* insert */ true);
    assert(label_state);

    // TODO: Determine if this is the correct semantics for insert label vs. begin/end, perserving existing semantics for now
    label_state->insert_label = LoggingLabel(label_info);
}

// Current tracking beyond a single command buffer scope is incorrect, and even when it is we need to be able to clean up
static inline void ResetCmdDebugUtilsLabel(debug_report_data *report_data, VkCommandBuffer command_buffer) {
    std::unique_lock<std::mutex> lock(report_data->debug_output_mutex);
    auto *label_state = GetLoggingLabelState(&report_data->debugUtilsCmdBufLabels, command_buffer, /* insert */ false);
    if (label_state) {
        label_state->labels.clear();
        label_state->insert_label.Reset();
    }
}

static inline void EraseCmdDebugUtilsLabel(debug_report_data *report_data, VkCommandBuffer command_buffer) {
    report_data->debugUtilsCmdBufLabels.erase(command_buffer);
}

#endif  // LAYER_LOGGING_H
