/* Copyright (c) 2015-2016 The Khronos Group Inc.
 * Copyright (c) 2015-2016 Valve Corporation
 * Copyright (c) 2015-2016 LunarG, Inc.
 * Copyright (C) 2015-2016 Google 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: Dustin Graves <dustin@lunarg.com>
 */

#ifndef PARAMETER_VALIDATION_UTILS_H
#define PARAMETER_VALIDATION_UTILS_H

#include <algorithm>
#include <cstdlib>
#include <string>
#include <sstream>
#include <bitset>
#include <mutex>
#include <unordered_map>
#include <unordered_set>

#include "vulkan/vulkan.h"
#include "vk_enum_string_helper.h"
#include "vk_layer_logging.h"
#include "vk_validation_error_messages.h"
#include "vk_extension_helper.h"
#include "vk_layer_utils.h"

#include "parameter_name.h"

namespace parameter_validation {

extern const uint32_t GeneratedHeaderVersion;
extern const std::unordered_map<std::string, void *> name_to_funcptr_map;

extern const VkQueryPipelineStatisticFlags AllVkQueryPipelineStatisticFlagBits;
extern const VkColorComponentFlags AllVkColorComponentFlagBits;
extern const VkShaderStageFlags AllVkShaderStageFlagBits;
extern const VkQueryControlFlags AllVkQueryControlFlagBits;
extern const VkImageUsageFlags AllVkImageUsageFlagBits;

extern const std::vector<VkCompareOp> AllVkCompareOpEnums;
extern const std::vector<VkStencilOp> AllVkStencilOpEnums;
extern const std::vector<VkBlendFactor> AllVkBlendFactorEnums;
extern const std::vector<VkBlendOp> AllVkBlendOpEnums;
extern const std::vector<VkLogicOp> AllVkLogicOpEnums;
extern const std::vector<VkBorderColor> AllVkBorderColorEnums;
extern const std::vector<VkImageLayout> AllVkImageLayoutEnums;

struct instance_layer_data {
    VkInstance instance = VK_NULL_HANDLE;

    debug_report_data *report_data = nullptr;
    std::vector<VkDebugReportCallbackEXT> logging_callback;
    std::vector<VkDebugUtilsMessengerEXT> logging_messenger;

    // The following are for keeping track of the temporary callbacks that can
    // be used in vkCreateInstance and vkDestroyInstance:
    uint32_t num_tmp_report_callbacks = 0;
    VkDebugReportCallbackCreateInfoEXT *tmp_report_create_infos = nullptr;
    VkDebugReportCallbackEXT *tmp_report_callbacks = nullptr;
    uint32_t num_tmp_debug_messengers = 0;
    VkDebugUtilsMessengerCreateInfoEXT *tmp_messenger_create_infos = nullptr;
    VkDebugUtilsMessengerEXT *tmp_debug_messengers = nullptr;

    InstanceExtensions extensions = {};
    VkLayerInstanceDispatchTable dispatch_table = {};
    uint32_t api_version;
};

struct layer_data {
    debug_report_data *report_data = nullptr;
    // Map for queue family index to queue count
    std::unordered_map<uint32_t, uint32_t> queueFamilyIndexMap;
    VkPhysicalDeviceLimits device_limits = {};
    VkPhysicalDeviceFeatures physical_device_features = {};
    VkPhysicalDevice physical_device = VK_NULL_HANDLE;
    VkDevice device = VK_NULL_HANDLE;
    DeviceExtensions extensions;
    uint32_t api_version;

    // Device extension properties -- storing properties gathered from VkPhysicalDeviceProperties2KHR::pNext chain
    struct DeviceExtensionProperties {
        VkPhysicalDeviceShadingRateImagePropertiesNV shading_rate_image_props;
        VkPhysicalDeviceMeshShaderPropertiesNV mesh_shader_props;
    };
    DeviceExtensionProperties phys_dev_ext_props = {};

    struct SubpassesUsageStates {
        std::unordered_set<uint32_t> subpasses_using_color_attachment;
        std::unordered_set<uint32_t> subpasses_using_depthstencil_attachment;
    };

    std::unordered_map<VkRenderPass, SubpassesUsageStates> renderpasses_states;

    VkLayerDispatchTable dispatch_table = {};
};

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

static const char DECORATE_UNUSED *kVUID_PVError_NONE = "UNASSIGNED-GeneralParameterError-Info";
static const char DECORATE_UNUSED *kVUID_PVError_InvalidUsage = "UNASSIGNED-GeneralParameterError-InvalidUsage";
static const char DECORATE_UNUSED *kVUID_PVError_InvalidStructSType = "UNASSIGNED-GeneralParameterError-InvalidStructSType";
static const char DECORATE_UNUSED *kVUID_PVError_InvalidStructPNext = "UNASSIGNED-GeneralParameterError-InvalidStructPNext";
static const char DECORATE_UNUSED *kVUID_PVError_RequiredParameter = "UNASSIGNED-GeneralParameterError-RequiredParameter";
static const char DECORATE_UNUSED *kVUID_PVError_ReservedParameter = "UNASSIGNED-GeneralParameterError-ReservedParameter";
static const char DECORATE_UNUSED *kVUID_PVError_UnrecognizedValue = "UNASSIGNED-GeneralParameterError-UnrecognizedValue";
static const char DECORATE_UNUSED *kVUID_PVError_DeviceLimit = "UNASSIGNED-GeneralParameterError-DeviceLimit";
static const char DECORATE_UNUSED *kVUID_PVError_DeviceFeature = "UNASSIGNED-GeneralParameterError-DeviceFeature";
static const char DECORATE_UNUSED *kVUID_PVError_FailureCode = "UNASSIGNED-GeneralParameterError-FailureCode";
static const char DECORATE_UNUSED *kVUID_PVError_ExtensionNotEnabled = "UNASSIGNED-GeneralParameterError-ExtensionNotEnabled";

#undef DECORATE_UNUSED

#if 0  // TBD - should see if we can add the expository text below into the spec reference string database
enum ErrorCode {
    NONE,                   // Used for INFO & other non-error messages
    INVALID_USAGE,          // The value of a parameter is not consistent
                            // with the valid usage criteria defined in
                            // the Vulkan specification.
    INVALID_STRUCT_STYPE,   // The sType field of a Vulkan structure does
                            // not contain the value expected for a structure
                            // of that type.
    INVALID_STRUCT_PNEXT,   // The pNext field of a Vulkan structure references
                            // a value that is not compatible with a structure of
                            // that type or is not NULL when a structure of that
                            // type has no compatible pNext values.
    REQUIRED_PARAMETER,     // A required parameter was specified as 0 or NULL.
    RESERVED_PARAMETER,     // A parameter reserved for future use was not
                            // specified as 0 or NULL.
    UNRECOGNIZED_VALUE,     // A Vulkan enumeration, VkFlags, or VkBool32 parameter
                            // contains a value that is not recognized as valid for
                            // that type.
    DEVICE_LIMIT,           // A specified parameter exceeds the limits returned
                            // by the physical device
    DEVICE_FEATURE,         // Use of a requested feature is not supported by
                            // the device
    FAILURE_RETURN_CODE,    // A Vulkan return code indicating a failure condition
                            // was encountered.
    EXTENSION_NOT_ENABLED,  // An extension entrypoint was called, but the required
                            // extension was not enabled at CreateInstance or
                            // CreateDevice time.
};
#endif

struct GenericHeader {
    VkStructureType sType;
    const void *pNext;
};

// String returned by string_VkStructureType for an unrecognized type.
const std::string UnsupportedStructureTypeString = "Unhandled VkStructureType";

// String returned by string_VkResult for an unrecognized type.
const std::string UnsupportedResultString = "Unhandled VkResult";

// The base value used when computing the offset for an enumeration token value that is added by an extension.
// When validating enumeration tokens, any value >= to this value is considered to be provided by an extension.
// See Appendix C.10 "Assigning Extension Token Values" from the Vulkan specification
const uint32_t ExtEnumBaseValue = 1000000000;

// The value of all VK_xxx_MAX_ENUM tokens
const uint32_t MaxEnumValue = 0x7FFFFFFF;

// Misc parameters of log_msg that are likely constant per command (or low frequency change)
struct LogMiscParams {
    const debug_report_data *debug_data;
    VkDebugReportObjectTypeEXT objectType;
    uint64_t srcObject;
    const char *api_name;
};

// Pick up VUIDS from validated substructures. Many structures contain substructures.  In addition to the implicit VUs covered
// when each of the substructures is parsed, there is often a VUID for 'xxx MUST be a valid XxxStruct'. If all implicit valid usage
// is covered for a substructure, we should claim the VUID for the validity of the structure itself.
static bool ValidateSubstructure(debug_report_data *report_data, const char *api_name, const char *struct_name,
                                 const std::string &substructure_vuid) {
    bool skip = false;
    if (false) {
        skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, substructure_vuid,
                        "%s: parameter %s must be a valid structure.", api_name, struct_name);
    }
    return skip;
}

/**
 * Validate a minimum value.
 *
 * Verify that the specified value is greater than the specified lower bound.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param api_name Name of API call being validated.
 * @param parameter_name Name of parameter being validated.
 * @param value Value to validate.
 * @param lower_bound Lower bound value to use for validation.
 * @return Boolean value indicating that the call should be skipped.
 */
template <typename T>
bool ValidateGreaterThan(const T value, const T lower_bound, const ParameterName &parameter_name, const std::string &vuid,
                         const LogMiscParams &misc) {
    bool skip_call = false;

    if (value <= lower_bound) {
        std::ostringstream ss;
        ss << misc.api_name << ": parameter " << parameter_name.get_name() << " (= " << value << ") is greater than "
           << lower_bound;
        skip_call |=
            log_msg(misc.debug_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, misc.objectType, misc.srcObject, vuid, "%s", ss.str().c_str());
    }

    return skip_call;
}

template <typename T>
bool ValidateGreaterThanZero(const T value, const ParameterName &parameter_name, const std::string &vuid,
                             const LogMiscParams &misc) {
    return ValidateGreaterThan(value, T{0}, parameter_name, vuid, misc);
}
/**
 * Validate a required pointer.
 *
 * Verify that a required pointer is not NULL.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param parameterName Name of parameter being validated.
 * @param value Pointer to validate.
 * @return Boolean value indicating that the call should be skipped.
 */
static bool validate_required_pointer(debug_report_data *report_data, const char *apiName, const ParameterName &parameterName,
                                      const void *value, const std::string &vuid) {
    bool skip_call = false;

    if (value == NULL) {
        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid,
                             "%s: required parameter %s specified as NULL.", apiName, parameterName.get_name().c_str());
    }

    return skip_call;
}

/**
 * Validate array count and pointer to array.
 *
 * Verify that required count and array parameters are not 0 or NULL.  If the
 * count parameter is not optional, verify that it is not 0.  If the array
 * parameter is NULL, and it is not optional, verify that count is 0.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param countName Name of count parameter.
 * @param arrayName Name of array parameter.
 * @param count Number of elements in the array.
 * @param array Array to validate.
 * @param countRequired The 'count' parameter may not be 0 when true.
 * @param arrayRequired The 'array' parameter may not be NULL when true.
 * @return Boolean value indicating that the call should be skipped.
 */
template <typename T1, typename T2>
bool validate_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName,
                    const ParameterName &arrayName, T1 count, const T2 *array, bool countRequired, bool arrayRequired,
                    const std::string &count_required_vuid, const std::string &array_required_vuid) {
    bool skip_call = false;

    // Count parameters not tagged as optional cannot be 0
    if (countRequired && (count == 0)) {
        skip_call |=
            log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, count_required_vuid,
                    "%s: parameter %s must be greater than 0.", apiName, countName.get_name().c_str());
    }

    // Array parameters not tagged as optional cannot be NULL, unless the count is 0
    if (arrayRequired && (count != 0) && (*array == NULL)) {
        skip_call |=
            log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, array_required_vuid,
                    "%s: required parameter %s specified as NULL.", apiName, arrayName.get_name().c_str());
    }

    return skip_call;
}

/**
 * Validate pointer to array count and pointer to array.
 *
 * Verify that required count and array parameters are not NULL.  If count
 * is not NULL and its value is not optional, verify that it is not 0.  If the
 * array parameter is NULL, and it is not optional, verify that count is 0.
 * The array parameter will typically be optional for this case (where count is
 * a pointer), allowing the caller to retrieve the available count.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param countName Name of count parameter.
 * @param arrayName Name of array parameter.
 * @param count Pointer to the number of elements in the array.
 * @param array Array to validate.
 * @param countPtrRequired The 'count' parameter may not be NULL when true.
 * @param countValueRequired The '*count' value may not be 0 when true.
 * @param arrayRequired The 'array' parameter may not be NULL when true.
 * @return Boolean value indicating that the call should be skipped.
 */
template <typename T1, typename T2>
bool validate_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName,
                    const ParameterName &arrayName, const T1 *count, const T2 *array, bool countPtrRequired,
                    bool countValueRequired, bool arrayRequired, const std::string &count_required_vuid,
                    const std::string &array_required_vuid) {
    bool skip_call = false;

    if (count == NULL) {
        if (countPtrRequired) {
            skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                 kVUID_PVError_RequiredParameter, "%s: required parameter %s specified as NULL", apiName,
                                 countName.get_name().c_str());
        }
    } else {
        skip_call |= validate_array(report_data, apiName, countName, arrayName, *array ? (*count) : 0, &array, countValueRequired,
                                    arrayRequired, count_required_vuid, array_required_vuid);
    }

    return skip_call;
}

/**
 * Validate a pointer to a Vulkan structure.
 *
 * Verify that a required pointer to a structure is not NULL.  If the pointer is
 * not NULL, verify that each structure's sType field is set to the correct
 * VkStructureType value.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param parameterName Name of struct parameter being validated.
 * @param sTypeName Name of expected VkStructureType value.
 * @param value Pointer to the struct to validate.
 * @param sType VkStructureType for structure validation.
 * @param required The parameter may not be NULL when true.
 * @return Boolean value indicating that the call should be skipped.
 */
template <typename T>
bool validate_struct_type(debug_report_data *report_data, const char *apiName, const ParameterName &parameterName,
                          const char *sTypeName, const T *value, VkStructureType sType, bool required,
                          const std::string &struct_vuid, const std::string &stype_vuid) {
    bool skip_call = false;

    if (value == NULL) {
        if (required) {
            skip_call |=
                log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, struct_vuid,
                        "%s: required parameter %s specified as NULL", apiName, parameterName.get_name().c_str());
        }
    } else if (value->sType != sType) {
        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, stype_vuid,
                             "%s: parameter %s->sType must be %s.", apiName, parameterName.get_name().c_str(), sTypeName);
    }

    return skip_call;
}

/**
 * Validate an array of Vulkan structures
 *
 * Verify that required count and array parameters are not 0 or NULL.  If
 * the array contains 1 or more structures, verify that each structure's
 * sType field is set to the correct VkStructureType value.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param countName Name of count parameter.
 * @param arrayName Name of array parameter.
 * @param sTypeName Name of expected VkStructureType value.
 * @param count Number of elements in the array.
 * @param array Array to validate.
 * @param sType VkStructureType for structure validation.
 * @param countRequired The 'count' parameter may not be 0 when true.
 * @param arrayRequired The 'array' parameter may not be NULL when true.
 * @return Boolean value indicating that the call should be skipped.
 */
template <typename T>
bool validate_struct_type_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName,
                                const ParameterName &arrayName, const char *sTypeName, uint32_t count, const T *array,
                                VkStructureType sType, bool countRequired, bool arrayRequired, const std::string &stype_vuid,
                                const std::string &param_vuid) {
    bool skip_call = false;

    if ((count == 0) || (array == NULL)) {
        skip_call |= validate_array(report_data, apiName, countName, arrayName, count, &array, countRequired, arrayRequired,
                                    kVUIDUndefined, param_vuid);
    } else {
        // Verify that all structs in the array have the correct type
        for (uint32_t i = 0; i < count; ++i) {
            if (array[i].sType != sType) {
                skip_call |=
                    log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, stype_vuid,
                            "%s: parameter %s[%d].sType must be %s", apiName, arrayName.get_name().c_str(), i, sTypeName);
            }
        }
    }

    return skip_call;
}

/**
 * Validate an array of Vulkan structures.
 *
 * Verify that required count and array parameters are not NULL.  If count
 * is not NULL and its value is not optional, verify that it is not 0.
 * If the array contains 1 or more structures, verify that each structure's
 * sType field is set to the correct VkStructureType value.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param countName Name of count parameter.
 * @param arrayName Name of array parameter.
 * @param sTypeName Name of expected VkStructureType value.
 * @param count Pointer to the number of elements in the array.
 * @param array Array to validate.
 * @param sType VkStructureType for structure validation.
 * @param countPtrRequired The 'count' parameter may not be NULL when true.
 * @param countValueRequired The '*count' value may not be 0 when true.
 * @param arrayRequired The 'array' parameter may not be NULL when true.
 * @return Boolean value indicating that the call should be skipped.
 */
template <typename T>
bool validate_struct_type_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName,
                                const ParameterName &arrayName, const char *sTypeName, uint32_t *count, const T *array,
                                VkStructureType sType, bool countPtrRequired, bool countValueRequired, bool arrayRequired,
                                const std::string &stype_vuid, const std::string &param_vuid) {
    bool skip_call = false;

    if (count == NULL) {
        if (countPtrRequired) {
            skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                 kVUID_PVError_RequiredParameter, "%s: required parameter %s specified as NULL", apiName,
                                 countName.get_name().c_str());
        }
    } else {
        skip_call |= validate_struct_type_array(report_data, apiName, countName, arrayName, sTypeName, (*count), array, sType,
                                                countValueRequired, arrayRequired, stype_vuid, param_vuid);
    }

    return skip_call;
}

/**
 * Validate a Vulkan handle.
 *
 * Verify that the specified handle is not VK_NULL_HANDLE.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param api_name Name of API call being validated.
 * @param parameter_name Name of struct parameter being validated.
 * @param value Handle to validate.
 * @return Boolean value indicating that the call should be skipped.
 */
template <typename T>
bool validate_required_handle(debug_report_data *report_data, const char *api_name, const ParameterName &parameter_name, T value) {
    bool skip_call = false;

    if (value == VK_NULL_HANDLE) {
        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                             kVUID_PVError_RequiredParameter, "%s: required parameter %s specified as VK_NULL_HANDLE", api_name,
                             parameter_name.get_name().c_str());
    }

    return skip_call;
}

/**
 * Validate an array of Vulkan handles.
 *
 * Verify that required count and array parameters are not NULL.  If count
 * is not NULL and its value is not optional, verify that it is not 0.
 * If the array contains 1 or more handles, verify that no handle is set to
 * VK_NULL_HANDLE.
 *
 * @note This function is only intended to validate arrays of handles when none
 *       of the handles are allowed to be VK_NULL_HANDLE.  For arrays of handles
 *       that are allowed to contain VK_NULL_HANDLE, use validate_array() instead.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param api_name Name of API call being validated.
 * @param count_name Name of count parameter.
 * @param array_name Name of array parameter.
 * @param count Number of elements in the array.
 * @param array Array to validate.
 * @param count_required The 'count' parameter may not be 0 when true.
 * @param array_required The 'array' parameter may not be NULL when true.
 * @return Boolean value indicating that the call should be skipped.
 */
template <typename T>
bool validate_handle_array(debug_report_data *report_data, const char *api_name, const ParameterName &count_name,
                           const ParameterName &array_name, uint32_t count, const T *array, bool count_required,
                           bool array_required) {
    bool skip_call = false;

    if ((count == 0) || (array == NULL)) {
        skip_call |= validate_array(report_data, api_name, count_name, array_name, count, &array, count_required, array_required,
                                    kVUIDUndefined, kVUIDUndefined);
    } else {
        // Verify that no handles in the array are VK_NULL_HANDLE
        for (uint32_t i = 0; i < count; ++i) {
            if (array[i] == VK_NULL_HANDLE) {
                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                     kVUID_PVError_RequiredParameter, "%s: required parameter %s[%d] specified as VK_NULL_HANDLE",
                                     api_name, array_name.get_name().c_str(), i);
            }
        }
    }

    return skip_call;
}

/**
 * Validate string array count and content.
 *
 * Verify that required count and array parameters are not 0 or NULL.  If the
 * count parameter is not optional, verify that it is not 0.  If the array
 * parameter is NULL, and it is not optional, verify that count is 0.  If the
 * array parameter is not NULL, verify that none of the strings are NULL.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param countName Name of count parameter.
 * @param arrayName Name of array parameter.
 * @param count Number of strings in the array.
 * @param array Array of strings to validate.
 * @param countRequired The 'count' parameter may not be 0 when true.
 * @param arrayRequired The 'array' parameter may not be NULL when true.
 * @return Boolean value indicating that the call should be skipped.
 */
static bool validate_string_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName,
                                  const ParameterName &arrayName, uint32_t count, const char *const *array, bool countRequired,
                                  bool arrayRequired, const std::string &count_required_vuid,
                                  const std::string &array_required_vuid) {
    bool skip_call = false;

    if ((count == 0) || (array == NULL)) {
        skip_call |= validate_array(report_data, apiName, countName, arrayName, count, &array, countRequired, arrayRequired,
                                    count_required_vuid, array_required_vuid);
    } else {
        // Verify that strings in the array are not NULL
        for (uint32_t i = 0; i < count; ++i) {
            if (array[i] == NULL) {
                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                     kVUID_PVError_RequiredParameter, "%s: required parameter %s[%d] specified as NULL", apiName,
                                     arrayName.get_name().c_str(), i);
            }
        }
    }

    return skip_call;
}

// Forward declaration for pNext validation
bool ValidatePnextStructContents(debug_report_data *report_data, const char *api_name, const ParameterName &parameter_name,
                                 const GenericHeader *header);

/**
 * Validate a structure's pNext member.
 *
 * Verify that the specified pNext value points to the head of a list of
 * allowed extension structures.  If no extension structures are allowed,
 * verify that pNext is null.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param api_name Name of API call being validated.
 * @param parameter_name Name of parameter being validated.
 * @param allowed_struct_names Names of allowed structs.
 * @param next Pointer to validate.
 * @param allowed_type_count Total number of allowed structure types.
 * @param allowed_types Array of structure types allowed for pNext.
 * @param header_version Version of header defining the pNext validation rules.
 * @return Boolean value indicating that the call should be skipped.
 */
static bool validate_struct_pnext(debug_report_data *report_data, const char *api_name, const ParameterName &parameter_name,
                                  const char *allowed_struct_names, const void *next, size_t allowed_type_count,
                                  const VkStructureType *allowed_types, uint32_t header_version, const std::string &vuid) {
    bool skip_call = false;
    std::unordered_set<const void *> cycle_check;
    std::unordered_set<VkStructureType, std::hash<int>> unique_stype_check;

    const char disclaimer[] =
        "This warning is based on the Valid Usage documentation for version %d of the Vulkan header.  It is possible that you are "
        "using a struct from a private extension or an extension that was added to a later version of the Vulkan header, in which "
        "case your use of %s is perfectly valid but is not guaranteed to work correctly with validation enabled";

    // TODO: The valid pNext structure types are not recursive. Each structure has its own list of valid sTypes for pNext.
    // Codegen a map of vectors containing the allowable pNext types for each struct and use that here -- also simplifies parms.
    if (next != NULL) {
        if (allowed_type_count == 0) {
            std::string message = "%s: value of %s must be NULL. ";
            message += disclaimer;
            skip_call |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid,
                                 message.c_str(), api_name, parameter_name.get_name().c_str(), header_version,
                                 parameter_name.get_name().c_str());
        } else {
            const VkStructureType *start = allowed_types;
            const VkStructureType *end = allowed_types + allowed_type_count;
            const GenericHeader *current = reinterpret_cast<const GenericHeader *>(next);

            cycle_check.insert(next);

            while (current != NULL) {
                if (((strncmp(api_name, "vkCreateInstance", strlen(api_name)) != 0) ||
                     (current->sType != VK_STRUCTURE_TYPE_LOADER_INSTANCE_CREATE_INFO)) &&
                    ((strncmp(api_name, "vkCreateDevice", strlen(api_name)) != 0) ||
                     (current->sType != VK_STRUCTURE_TYPE_LOADER_DEVICE_CREATE_INFO))) {
                    if (cycle_check.find(current->pNext) != cycle_check.end()) {
                        std::string message = "%s: %s chain contains a cycle -- pNext pointer " PRIx64 " is repeated.";
                        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                             kVUID_PVError_InvalidStructPNext, message.c_str(), api_name,
                                             parameter_name.get_name().c_str(), reinterpret_cast<uint64_t>(next));
                        break;
                    } else {
                        cycle_check.insert(current->pNext);
                    }

                    std::string type_name = string_VkStructureType(current->sType);
                    if (unique_stype_check.find(current->sType) != unique_stype_check.end()) {
                        std::string message = "%s: %s chain contains duplicate structure types: %s appears multiple times.";
                        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                             kVUID_PVError_InvalidStructPNext, message.c_str(), api_name,
                                             parameter_name.get_name().c_str(), type_name.c_str());
                    } else {
                        unique_stype_check.insert(current->sType);
                    }

                    if (std::find(start, end, current->sType) == end) {
                        if (type_name == UnsupportedStructureTypeString) {
                            std::string message =
                                "%s: %s chain includes a structure with unknown VkStructureType (%d); Allowed structures are "
                                "[%s]. ";
                            message += disclaimer;
                            skip_call |=
                                log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                        vuid, message.c_str(), api_name, parameter_name.get_name().c_str(), current->sType,
                                        allowed_struct_names, header_version, parameter_name.get_name().c_str());
                        } else {
                            std::string message =
                                "%s: %s chain includes a structure with unexpected VkStructureType %s; Allowed structures are "
                                "[%s]. ";
                            message += disclaimer;
                            skip_call |=
                                log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                        vuid, message.c_str(), api_name, parameter_name.get_name().c_str(), type_name.c_str(),
                                        allowed_struct_names, header_version, parameter_name.get_name().c_str());
                        }
                    }
                    // LUGMAL Insert pNext struct check here:
                    skip_call |= ValidatePnextStructContents(report_data, api_name, parameter_name, current);
                }
                current = reinterpret_cast<const GenericHeader *>(current->pNext);
            }
        }
    }

    return skip_call;
}

/**
 * Validate a VkBool32 value.
 *
 * Generate a warning if a VkBool32 value is neither VK_TRUE nor VK_FALSE.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param parameterName Name of parameter being validated.
 * @param value Boolean value to validate.
 * @return Boolean value indicating that the call should be skipped.
 */
static bool validate_bool32(debug_report_data *report_data, const char *apiName, const ParameterName &parameterName,
                            VkBool32 value) {
    bool skip_call = false;

    if ((value != VK_TRUE) && (value != VK_FALSE)) {
        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                             kVUID_PVError_UnrecognizedValue, "%s: value of %s (%d) is neither VK_TRUE nor VK_FALSE", apiName,
                             parameterName.get_name().c_str(), value);
    }

    return skip_call;
}

/**
 * Validate a Vulkan enumeration value.
 *
 * Generate a warning if an enumeration token value does not fall within the core enumeration
 * begin and end token values, and was not added to the enumeration by an extension.  Extension
 * provided enumerations use the equation specified in Appendix C.10 of the Vulkan specification,
 * with 1,000,000,000 as the base token value.
 *
 * @note This function does not expect to process enumerations defining bitmask flag bits.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param parameterName Name of parameter being validated.
 * @param enumName Name of the enumeration being validated.
 * @param valid_values The list of valid values for the enumeration.
 * @param value Enumeration value to validate.
 * @return Boolean value indicating that the call should be skipped.
 */
template <typename T>
bool validate_ranged_enum(debug_report_data *report_data, const char *apiName, const ParameterName &parameterName,
                          const char *enumName, const std::vector<T> &valid_values, T value, const std::string &vuid) {
    bool skip = false;

    if (std::find(valid_values.begin(), valid_values.end(), value) == valid_values.end()) {
        skip |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid,
                        "%s: value of %s (%d) does not fall within the begin..end range of the core %s enumeration tokens and is "
                        "not an extension added token.",
                        apiName, parameterName.get_name().c_str(), value, enumName);
    }

    return skip;
}

/**
 * Validate an array of Vulkan enumeration value.
 *
 * Process all enumeration token values in the specified array and generate a warning if a value
 * does not fall within the core enumeration begin and end token values, and was not added to
 * the enumeration by an extension.  Extension provided enumerations use the equation specified
 * in Appendix C.10 of the Vulkan specification, with 1,000,000,000 as the base token value.
 *
 * @note This function does not expect to process enumerations defining bitmask flag bits.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param countName Name of count parameter.
 * @param arrayName Name of array parameter.
 * @param enumName Name of the enumeration being validated.
 * @param valid_values The list of valid values for the enumeration.
 * @param count Number of enumeration values in the array.
 * @param array Array of enumeration values to validate.
 * @param countRequired The 'count' parameter may not be 0 when true.
 * @param arrayRequired The 'array' parameter may not be NULL when true.
 * @return Boolean value indicating that the call should be skipped.
 */
template <typename T>
static bool validate_ranged_enum_array(debug_report_data *report_data, const char *apiName, const ParameterName &countName,
                                       const ParameterName &arrayName, const char *enumName, const std::vector<T> &valid_values,
                                       uint32_t count, const T *array, bool countRequired, bool arrayRequired) {
    bool skip_call = false;

    if ((count == 0) || (array == NULL)) {
        skip_call |= validate_array(report_data, apiName, countName, arrayName, count, &array, countRequired, arrayRequired,
                                    kVUIDUndefined, kVUIDUndefined);
    } else {
        for (uint32_t i = 0; i < count; ++i) {
            if (std::find(valid_values.begin(), valid_values.end(), array[i]) == valid_values.end()) {
                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                     kVUID_PVError_UnrecognizedValue,
                                     "%s: value of %s[%d] (%d) does not fall within the begin..end range of the core %s "
                                     "enumeration tokens and is not an extension added token",
                                     apiName, arrayName.get_name().c_str(), i, array[i], enumName);
            }
        }
    }

    return skip_call;
}

/**
 * Verify that a reserved VkFlags value is zero.
 *
 * Verify that the specified value is zero, to check VkFlags values that are reserved for
 * future use.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param api_name Name of API call being validated.
 * @param parameter_name Name of parameter being validated.
 * @param value Value to validate.
 * @return Boolean value indicating that the call should be skipped.
 */
static bool validate_reserved_flags(debug_report_data *report_data, const char *api_name, const ParameterName &parameter_name,
                                    VkFlags value, const std::string &vuid) {
    bool skip_call = false;

    if (value != 0) {
        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid,
                             "%s: parameter %s must be 0.", api_name, parameter_name.get_name().c_str());
    }

    return skip_call;
}

/**
 * Validate a Vulkan bitmask value.
 *
 * Generate a warning if a value with a VkFlags derived type does not contain valid flag bits
 * for that type.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param api_name Name of API call being validated.
 * @param parameter_name Name of parameter being validated.
 * @param flag_bits_name Name of the VkFlags type being validated.
 * @param all_flags A bit mask combining all valid flag bits for the VkFlags type being validated.
 * @param value VkFlags value to validate.
 * @param flags_required The 'value' parameter may not be 0 when true.
 * @param singleFlag The 'value' parameter may not contain more than one bit from all_flags.
 * @return Boolean value indicating that the call should be skipped.
 */
static bool validate_flags(debug_report_data *report_data, const char *api_name, const ParameterName &parameter_name,
                           const char *flag_bits_name, VkFlags all_flags, VkFlags value, bool flags_required, bool singleFlag,
                           const std::string &vuid) {
    bool skip_call = false;

    if (value == 0) {
        if (flags_required) {
            skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0, vuid,
                                 "%s: value of %s must not be 0.", api_name, parameter_name.get_name().c_str());
        }
    } else if ((value & (~all_flags)) != 0) {
        skip_call |=
            log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                    kVUID_PVError_UnrecognizedValue, "%s: value of %s contains flag bits that are not recognized members of %s",
                    api_name, parameter_name.get_name().c_str(), flag_bits_name);
    } else if (singleFlag && (std::bitset<sizeof(VkFlags) * 8>(value).count() > 1)) {
        skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                             kVUID_PVError_UnrecognizedValue,
                             "%s: value of %s contains multiple members of %s when only a single value is allowed", api_name,
                             parameter_name.get_name().c_str(), flag_bits_name);
    }

    return skip_call;
}

/**
 * Validate an array of Vulkan bitmask values.
 *
 * Generate a warning if a value with a VkFlags derived type does not contain valid flag bits
 * for that type.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param api_name Name of API call being validated.
 * @param count_name Name of parameter being validated.
 * @param array_name Name of parameter being validated.
 * @param flag_bits_name Name of the VkFlags type being validated.
 * @param all_flags A bitmask combining all valid flag bits for the VkFlags type being validated.
 * @param count Number of VkFlags values in the array.
 * @param array Array of VkFlags value to validate.
 * @param count_required The 'count' parameter may not be 0 when true.
 * @param array_required The 'array' parameter may not be NULL when true.
 * @return Boolean value indicating that the call should be skipped.
 */
static bool validate_flags_array(debug_report_data *report_data, const char *api_name, const ParameterName &count_name,
                                 const ParameterName &array_name, const char *flag_bits_name, VkFlags all_flags, uint32_t count,
                                 const VkFlags *array, bool count_required, bool array_required) {
    bool skip_call = false;

    if ((count == 0) || (array == NULL)) {
        skip_call |= validate_array(report_data, api_name, count_name, array_name, count, &array, count_required, array_required,
                                    kVUIDUndefined, kVUIDUndefined);
    } else {
        // Verify that all VkFlags values in the array
        for (uint32_t i = 0; i < count; ++i) {
            if (array[i] == 0) {
                // Current XML registry logic for validity generation uses the array parameter's optional tag to determine if
                // elements in the array are allowed be 0
                if (array_required) {
                    skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                         kVUID_PVError_RequiredParameter, "%s: value of %s[%d] must not be 0", api_name,
                                         array_name.get_name().c_str(), i);
                }
            } else if ((array[i] & (~all_flags)) != 0) {
                skip_call |= log_msg(report_data, VK_DEBUG_REPORT_ERROR_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                                     kVUID_PVError_UnrecognizedValue,
                                     "%s: value of %s[%d] contains flag bits that are not recognized members of %s", api_name,
                                     array_name.get_name().c_str(), i, flag_bits_name);
            }
        }
    }

    return skip_call;
}

/**
 * Get VkResult code description.
 *
 * Returns a string describing the specified VkResult code.  The description is based on the language in the Vulkan API
 * specification.
 *
 * @param value VkResult code to process.
 * @return String describing the specified VkResult code.
 */
static std::string get_result_description(VkResult result) {
    // clang-format off
    switch (result) {
        case VK_SUCCESS:                        return "a command completed successfully";
        case VK_NOT_READY:                      return "a fence or query has not yet completed";
        case VK_TIMEOUT:                        return "a wait operation has not completed in the specified time";
        case VK_EVENT_SET:                      return "an event is signaled";
        case VK_EVENT_RESET:                    return "an event is unsignalled";
        case VK_INCOMPLETE:                     return "a return array was too small for the result";
        case VK_ERROR_OUT_OF_HOST_MEMORY:       return "a host memory allocation has failed";
        case VK_ERROR_OUT_OF_DEVICE_MEMORY:     return "a device memory allocation has failed";
        case VK_ERROR_INITIALIZATION_FAILED:    return "initialization of an object has failed";
        case VK_ERROR_DEVICE_LOST:              return "the logical device has been lost";
        case VK_ERROR_MEMORY_MAP_FAILED:        return "mapping of a memory object has failed";
        case VK_ERROR_LAYER_NOT_PRESENT:        return "the specified layer does not exist";
        case VK_ERROR_EXTENSION_NOT_PRESENT:    return "the specified extension does not exist";
        case VK_ERROR_FEATURE_NOT_PRESENT:      return "the requested feature is not available on this device";
        case VK_ERROR_INCOMPATIBLE_DRIVER:      return "a Vulkan driver could not be found";
        case VK_ERROR_TOO_MANY_OBJECTS:         return "too many objects of the type have already been created";
        case VK_ERROR_FORMAT_NOT_SUPPORTED:     return "the requested format is not supported on this device";
        case VK_ERROR_SURFACE_LOST_KHR:         return "a surface is no longer available";
        case VK_ERROR_NATIVE_WINDOW_IN_USE_KHR: return "the requested window is already connected to another "
                                                       "VkSurfaceKHR object, or some other non-Vulkan surface object";
        case VK_SUBOPTIMAL_KHR:                 return "an image became available, and the swapchain no longer "
                                                       "matches the surface properties exactly, but can still be used to "
                                                       "present to the surface successfully.";
        case VK_ERROR_OUT_OF_DATE_KHR:          return "a surface has changed in such a way that it is no "
                                                       "longer compatible with the swapchain";
        case VK_ERROR_INCOMPATIBLE_DISPLAY_KHR: return "the display used by a swapchain does not use the same "
                                                       "presentable image layout, or is incompatible in a way that prevents "
                                                       "sharing an image";
        case VK_ERROR_VALIDATION_FAILED_EXT:    return "API validation has detected an invalid use of the API";
        case VK_ERROR_INVALID_SHADER_NV:        return "one or more shaders failed to compile or link";
        default:                                return "an error has occurred";
    };
    // clang-format on
}

/**
 * Validate return code.
 *
 * Print a message describing the reason for failure when an error code is returned.
 *
 * @param report_data debug_report_data object for routing validation messages.
 * @param apiName Name of API call being validated.
 * @param ignore vector of VkResult return codes to be ignored
 * @param value VkResult value to validate.
 */
static void validate_result(debug_report_data *report_data, const char *apiName, std::vector<VkResult> const &ignore,
                            VkResult result) {
    if (result < 0 && result != VK_ERROR_VALIDATION_FAILED_EXT) {
        if (std::find(ignore.begin(), ignore.end(), result) != ignore.end()) {
            return;
        }
        std::string resultName = string_VkResult(result);
        if (resultName == UnsupportedResultString) {
            // Unrecognized result code
            log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                    kVUID_PVError_FailureCode, "%s: returned a result code indicating that an error has occurred", apiName);
        } else {
            std::string resultDesc = get_result_description(result);
            log_msg(report_data, VK_DEBUG_REPORT_WARNING_BIT_EXT, VK_DEBUG_REPORT_OBJECT_TYPE_UNKNOWN_EXT, 0,
                    kVUID_PVError_FailureCode, "%s: returned %s, indicating that %s", apiName, resultName.c_str(),
                    resultDesc.c_str());
        }
    }
}

}  // namespace parameter_validation

#endif  // PARAMETER_VALIDATION_UTILS_H
