/*
 * Copyright (c) 2015-2016 The Khronos Group Inc.
 * Copyright (c) 2015-2016 Valve Corporation
 * Copyright (c) 2015-2016 LunarG, Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and/or associated documentation files (the "Materials"), to
 * deal in the Materials without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Materials, and to permit persons to whom the Materials are
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice(s) and this permission notice shall be included in
 * all copies or substantial portions of the Materials.
 *
 * THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 *
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
 * USE OR OTHER DEALINGS IN THE MATERIALS.
 *
 * Author: Jeremy Hayes <jeremy@lunarG.com>
 */

#include <algorithm>
#include <iostream>
#include <memory>
#include <string>
#include <vector>

#include <vulkan/vulkan.h>
#include "test_common.h"

namespace VK
{

struct InstanceCreateInfo
{
    InstanceCreateInfo() :
        info // MSVC can't handle list initialization, thus explicit construction herein.
        (
            VkInstanceCreateInfo
            {
                VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
                nullptr, // pNext
                0, // flags
                nullptr, // pApplicationInfo
                0, // enabledLayerCount
                nullptr, // ppEnabledLayerNames
                0, //enabledExtensionCount
                nullptr // ppEnabledExtensionNames
            }
        )
    {
    }

    InstanceCreateInfo& sType(VkStructureType const& sType)
    {
        info.sType = sType;

        return *this;
    }

    InstanceCreateInfo& pNext(void const*const pNext)
    {
        info.pNext = pNext;

        return *this;
    }

    InstanceCreateInfo& flags(VkInstanceCreateFlags const& flags)
    {
        info.flags = flags;

        return *this;
    }

    InstanceCreateInfo& pApplicationInfo(VkApplicationInfo const*const pApplicationInfo)
    {
        info.pApplicationInfo = pApplicationInfo;

        return *this;
    }

    InstanceCreateInfo& enabledLayerCount(uint32_t const& enabledLayerCount)
    {
        info.enabledLayerCount = enabledLayerCount;

        return *this;
    }

    InstanceCreateInfo& ppEnabledLayerNames(char const*const*const ppEnabledLayerNames)
    {
        info.ppEnabledLayerNames = ppEnabledLayerNames;

        return *this;
    }

    InstanceCreateInfo& enabledExtensionCount(uint32_t const& enabledExtensionCount)
    {
        info.enabledExtensionCount = enabledExtensionCount;

        return *this;
    }

    InstanceCreateInfo& ppEnabledExtensionNames(char const*const*const ppEnabledExtensionNames)
    {
        info.ppEnabledExtensionNames = ppEnabledExtensionNames;

        return *this;
    }

    operator VkInstanceCreateInfo const*() const
    {
        return &info;
    }

    operator VkInstanceCreateInfo*()
    {
        return &info;
    }

    VkInstanceCreateInfo info;
};

struct DeviceQueueCreateInfo
{
    DeviceQueueCreateInfo() :
        info // MSVC can't handle list initialization, thus explicit construction herein.
        (
            VkDeviceQueueCreateInfo
            {
                VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
                nullptr, // pNext
                0, // flags
                0, // queueFamilyIndex
                0, // queueCount
                nullptr // pQueuePriorities
            }
        )
    {
    }

    DeviceQueueCreateInfo& sType(VkStructureType const& sType)
    {
        info.sType = sType;

        return *this;
    }

    DeviceQueueCreateInfo& pNext(void const*const pNext)
    {
        info.pNext = pNext;

        return *this;
    }

    DeviceQueueCreateInfo& flags(VkDeviceQueueCreateFlags const& flags)
    {
        info.flags = flags;

        return *this;
    }

    DeviceQueueCreateInfo& queueFamilyIndex(uint32_t const& queueFamilyIndex)
    {
        info.queueFamilyIndex = queueFamilyIndex;

        return *this;
    }

    DeviceQueueCreateInfo& queueCount(uint32_t const& queueCount)
    {
        info.queueCount = queueCount;

        return *this;
    }

    DeviceQueueCreateInfo& pQueuePriorities(float const*const pQueuePriorities)
    {
        info.pQueuePriorities = pQueuePriorities;

        return *this;
    }

    operator VkDeviceQueueCreateInfo()
    {
        return info;
    }

    VkDeviceQueueCreateInfo info;
};

struct DeviceCreateInfo
{
    DeviceCreateInfo() :
        info // MSVC can't handle list initialization, thus explicit construction herein.
        (
            VkDeviceCreateInfo
            {
                VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
                nullptr, // pNext
                0, // flags
                0, // queueCreateInfoCount
                nullptr, // pQueueCreateInfos
                0, // enabledLayerCount
                nullptr, // ppEnabledLayerNames
                0, // enabledExtensionCount
                nullptr, // ppEnabledExtensionNames
                nullptr // pEnabledFeatures
            }
        )
    {
    }

    DeviceCreateInfo& sType(VkStructureType const& sType)
    {
        info.sType = sType;

        return *this;
    }

    DeviceCreateInfo& pNext(void const*const pNext)
    {
        info.pNext = pNext;

        return *this;
    }

    DeviceCreateInfo& flags(VkDeviceQueueCreateFlags const& flags)
    {
        info.flags = flags;

        return *this;
    }

    DeviceCreateInfo& queueCreateInfoCount(uint32_t const& queueCreateInfoCount)
    {
        info.queueCreateInfoCount = queueCreateInfoCount;

        return *this;
    }

    DeviceCreateInfo& pQueueCreateInfos(VkDeviceQueueCreateInfo const*const pQueueCreateInfos)
    {
        info.pQueueCreateInfos = pQueueCreateInfos;

        return *this;
    }

    DeviceCreateInfo& enabledLayerCount(uint32_t const& enabledLayerCount)
    {
        info.enabledLayerCount = enabledLayerCount;

        return *this;
    }

    DeviceCreateInfo& ppEnabledLayerNames(char const*const*const ppEnabledLayerNames)
    {
        info.ppEnabledLayerNames = ppEnabledLayerNames;

        return *this;
    }

    DeviceCreateInfo& enabledExtensionCount(uint32_t const& enabledExtensionCount)
    {
        info.enabledExtensionCount = enabledExtensionCount;

        return *this;
    }

    DeviceCreateInfo& ppEnabledExtensionNames(char const*const*const ppEnabledExtensionNames)
    {
        info.ppEnabledExtensionNames = ppEnabledExtensionNames;

        return *this;
    }

    DeviceCreateInfo& pEnabledFeatures(VkPhysicalDeviceFeatures const*const pEnabledFeatures)
    {
        info.pEnabledFeatures = pEnabledFeatures;

        return *this;
    }

    operator VkDeviceCreateInfo const*() const
    {
        return &info;
    }

    operator VkDeviceCreateInfo*()
    {
        return &info;
    }

    VkDeviceCreateInfo info;
};

}

struct CommandLine : public ::testing::Test
{
    static void Initialize(int argc, char **argv)
    {
        arguments.assign(argv, argv + argc);
    };

    static void SetUpTestCase() {};
    static void TearDownTestCase() {};

    static std::vector<std::string> arguments;
};
std::vector<std::string> CommandLine::arguments;

struct EnumerateInstanceLayerProperties : public CommandLine {};
struct EnumerateInstanceExtensionProperties : public CommandLine {};

// Test groups:
// LX = lunar exchange
// LVLGH = loader and validation github
// LVLGL = lodaer and validation gitlab

TEST(LX435, InstanceCreateInfoConst)
{
    VkInstanceCreateInfo const info =
    {
        VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
        nullptr,
        0,
        nullptr,
        0,
        nullptr,
        0,
        nullptr
    };

    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(&info, VK_NULL_HANDLE, &instance);
    EXPECT_EQ(result, VK_SUCCESS);

    vkDestroyInstance(instance, nullptr);
}

TEST(LX475, DestroyInstanceNullHandle)
{
    vkDestroyInstance(VK_NULL_HANDLE, nullptr);
}

TEST(LX475, DestroyDeviceNullHandle)
{
    vkDestroyDevice(VK_NULL_HANDLE, nullptr);
}

TEST(CreateInstance, ExtensionNotPresent)
{
    char const*const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
    auto const info = VK::InstanceCreateInfo().
        enabledExtensionCount(1).
        ppEnabledExtensionNames(names);

    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);

    // It's not necessary to destroy the instance because it will not be created successfully.
}

TEST(CreateInstance, LayerNotPresent)
{
    char const*const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
    auto const info = VK::InstanceCreateInfo().
        enabledLayerCount(1).
        ppEnabledLayerNames(names);

    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_ERROR_LAYER_NOT_PRESENT);

    // It's not necessary to destroy the instance because it will not be created successfully.
}

// Used by run_loader_tests.sh to test for layer insertion.
TEST(CreateInstance, LayerPresent)
{
    char const*const names[] = {"VK_LAYER_LUNARG_parameter_validation"}; // Temporary required due to MSVC bug.
    auto const info = VK::InstanceCreateInfo().
        enabledLayerCount(1).
        ppEnabledLayerNames(names);

    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    vkDestroyInstance(instance, nullptr);
}

TEST(CreateDevice, ExtensionNotPresent)
{
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for(uint32_t p = 0; p < physicalCount; ++p)
    {
        uint32_t familyCount = 0;
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
        ASSERT_EQ(result, VK_SUCCESS);
        ASSERT_GT(familyCount, 0u);

        std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
        ASSERT_EQ(result, VK_SUCCESS);
        ASSERT_GT(familyCount, 0u);

        for(uint32_t q = 0; q < familyCount; ++q)
        {
            if(~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT)
            {
                continue;
            }

            float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
            VkDeviceQueueCreateInfo const queueInfo[1]
            {
                VK::DeviceQueueCreateInfo().
                    queueFamilyIndex(q).
                    queueCount(1).
                    pQueuePriorities(priorities)
            };

            char const*const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
            auto const deviceInfo = VK::DeviceCreateInfo().
                queueCreateInfoCount(1).
                pQueueCreateInfos(queueInfo).
                enabledExtensionCount(1).
                ppEnabledExtensionNames(names);

            VkDevice device;
            result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
            ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);

            // It's not necessary to destroy the device because it will not be created successfully.
        }
    }

    vkDestroyInstance(instance, nullptr);
}

// LX535 / MI-76: Device layers are deprecated.
// For backwards compatibility, they are allowed, but must be ignored.
// Ensure that no errors occur if a bogus device layer list is passed to vkCreateDevice.
TEST(CreateDevice, LayersNotPresent)
{
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for(uint32_t p = 0; p < physicalCount; ++p)
    {
        uint32_t familyCount = 0;
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
        ASSERT_EQ(result, VK_SUCCESS);
        ASSERT_GT(familyCount, 0u);

        std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
        ASSERT_EQ(result, VK_SUCCESS);
        ASSERT_GT(familyCount, 0u);

        for(uint32_t q = 0; q < familyCount; ++q)
        {
            if(~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT)
            {
                continue;
            }

            float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
            VkDeviceQueueCreateInfo const queueInfo[1]
            {
                VK::DeviceQueueCreateInfo().
                    queueFamilyIndex(q).
                    queueCount(1).
                    pQueuePriorities(priorities)
            };

            char const*const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
            auto const deviceInfo = VK::DeviceCreateInfo().
                queueCreateInfoCount(1).
                pQueueCreateInfos(queueInfo).
                enabledLayerCount(1).
                ppEnabledLayerNames(names);

            VkDevice device;
            result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
            ASSERT_EQ(result, VK_SUCCESS);

            vkDestroyDevice(device, nullptr);
        }
    }

    vkDestroyInstance(instance, nullptr);
}

TEST_F(EnumerateInstanceLayerProperties, PropertyCountLessThanAvailable)
{
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    // We need atleast two for the test to be relevant.
    if(count < 2u)
    {
        return;
    }

    std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    count = 1;
    result = vkEnumerateInstanceLayerProperties(&count, properties.get());
    ASSERT_EQ(result, VK_INCOMPLETE);
}

TEST(EnumerateDeviceLayerProperties, PropertyCountLessThanAvailable)
{
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for(uint32_t p = 0; p < physicalCount; ++p)
    {
        uint32_t count = 0u;
        result = vkEnumerateDeviceLayerProperties(physical[p], &count, nullptr);
        ASSERT_EQ(result, VK_SUCCESS);

        // We need atleast two for the test to be relevant.
        if(count < 2u)
        {
            continue;
        }

        std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
        count = 1;
        result = vkEnumerateDeviceLayerProperties(physical[p], &count, properties.get());
        ASSERT_EQ(result, VK_INCOMPLETE);
    }

    vkDestroyInstance(instance, nullptr);
}

TEST_F(EnumerateInstanceLayerProperties, Count)
{
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    if(std::find(arguments.begin(), arguments.end(), "count") != arguments.end())
    {
        std::cout << "count=" << count << '\n';
    }
}

TEST_F(EnumerateInstanceLayerProperties, OnePass)
{
    // Count required for this test.
    if(std::find(arguments.begin(), arguments.end(), "count") == arguments.end())
    {
        return;
    }

    uint32_t count = std::stoul(arguments[2]);

    std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    VkResult result = vkEnumerateInstanceLayerProperties(&count, properties.get());
    ASSERT_EQ(result, VK_SUCCESS);

    if(std::find(arguments.begin(), arguments.end(), "properties") != arguments.end())
    {
        for(uint32_t p = 0; p < count; ++p)
        {
            std::cout << "properties[" << p << "] ="
                << ' ' << properties[p].layerName
                << ' ' << properties[p].specVersion
                << ' ' << properties[p].implementationVersion
                << ' ' << properties[p].description << '\n';
        }
    }
}

TEST_F(EnumerateInstanceLayerProperties, TwoPass)
{
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
    result = vkEnumerateInstanceLayerProperties(&count, properties.get());
    ASSERT_EQ(result, VK_SUCCESS);

    if(std::find(arguments.begin(), arguments.end(), "properties") != arguments.end())
    {
        for(uint32_t p = 0; p < count; ++p)
        {
            std::cout << "properties[" << p << "] ="
                << ' ' << properties[p].layerName
                << ' ' << properties[p].specVersion
                << ' ' << properties[p].implementationVersion
                << ' ' << properties[p].description << '\n';
        }
    }
}

TEST_F(EnumerateInstanceExtensionProperties, PropertyCountLessThanAvailable)
{
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    // We need atleast two for the test to be relevant.
    if(count < 2u)
    {
        return;
    }

    std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    count = 1;
    result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    ASSERT_EQ(result, VK_INCOMPLETE);
}

TEST(EnumerateDeviceExtensionProperties, PropertyCountLessThanAvailable)
{
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for(uint32_t p = 0; p < physicalCount; ++p)
    {
        uint32_t count = 0u;
        result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
        ASSERT_EQ(result, VK_SUCCESS);

        // We need atleast two for the test to be relevant.
        if(count < 2u)
        {
            continue;
        }

        std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
        count = 1;
        result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
        ASSERT_EQ(result, VK_INCOMPLETE);
    }

    vkDestroyInstance(instance, nullptr);
}

TEST_F(EnumerateInstanceExtensionProperties, Count)
{
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    if(std::find(arguments.begin(), arguments.end(), "count") != arguments.end())
    {
        std::cout << "count=" << count << '\n';
    }
}

TEST_F(EnumerateInstanceExtensionProperties, OnePass)
{
    // Count required for this test.
    if(std::find(arguments.begin(), arguments.end(), "count") == arguments.end())
    {
        return;
    }

    uint32_t count = std::stoul(arguments[2]);

    std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    ASSERT_EQ(result, VK_SUCCESS);

    if(std::find(arguments.begin(), arguments.end(), "properties") != arguments.end())
    {
        for(uint32_t p = 0; p < count; ++p)
        {
            std::cout << "properties[" << p << "] ="
                << ' ' << properties[p].extensionName
                << ' ' << properties[p].specVersion << '\n';
        }
    }
}

TEST_F(EnumerateInstanceExtensionProperties, TwoPass)
{
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    ASSERT_EQ(result, VK_SUCCESS);

    if(std::find(arguments.begin(), arguments.end(), "properties") != arguments.end())
    {
        for(uint32_t p = 0; p < count; ++p)
        {
            std::cout << "properties[" << p << "] ="
                << ' ' << properties[p].extensionName
                << ' ' << properties[p].specVersion << '\n';
        }
    }
}

TEST_F(EnumerateInstanceExtensionProperties, InstanceExtensionEnumerated)
{
    uint32_t count = 0u;
    VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);

    std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
    result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
    ASSERT_EQ(result, VK_SUCCESS);

    ASSERT_NE(std::find_if(
        &properties[0],
        &properties[count],
        [](VkExtensionProperties const& properties)
        {
            return strcmp(properties.extensionName, "VK_KHR_surface") == 0;
        }),
        &properties[count]);
}

TEST(EnumerateDeviceExtensionProperties, DeviceExtensionEnumerated)
{
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for(uint32_t p = 0; p < physicalCount; ++p)
    {
        uint32_t count = 0u;
        result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
        ASSERT_EQ(result, VK_SUCCESS);

        std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
        result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
        ASSERT_EQ(result, VK_SUCCESS);

        ASSERT_NE(std::find_if(
            &properties[0],
            &properties[count],
            [](VkExtensionProperties const& properties)
            {
                return strcmp(properties.extensionName, "VK_KHR_swapchain") == 0;
            }),
            &properties[count]);
    }

    vkDestroyInstance(instance, nullptr);
}

TEST(WrapObjects, Insert)
{
    VkInstance instance = VK_NULL_HANDLE;
    VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
    ASSERT_EQ(result, VK_SUCCESS);

    uint32_t physicalCount = 0;
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
    result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
    ASSERT_EQ(result, VK_SUCCESS);
    ASSERT_GT(physicalCount, 0u);

    for(uint32_t p = 0; p < physicalCount; ++p)
    {
        uint32_t familyCount = 0;
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
        ASSERT_EQ(result, VK_SUCCESS);
        ASSERT_GT(familyCount, 0u);

        std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
        vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
        ASSERT_EQ(result, VK_SUCCESS);
        ASSERT_GT(familyCount, 0u);

        for(uint32_t q = 0; q < familyCount; ++q)
        {
            if(~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT)
            {
                continue;
            }

            float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
            VkDeviceQueueCreateInfo const queueInfo[1]
            {
                VK::DeviceQueueCreateInfo().
                    queueFamilyIndex(q).
                    queueCount(1).
                    pQueuePriorities(priorities)
            };

            auto const deviceInfo = VK::DeviceCreateInfo().
                queueCreateInfoCount(1).
                pQueueCreateInfos(queueInfo);

            VkDevice device;
            result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
            ASSERT_EQ(result, VK_SUCCESS);

            vkDestroyDevice(device, nullptr);
        }
    }

    vkDestroyInstance(instance, nullptr);
}

int main(int argc, char **argv)
{
    int result;

    ::testing::InitGoogleTest(&argc, argv);

    if(argc > 0)
    {
        CommandLine::Initialize(argc, argv);
    }

    result = RUN_ALL_TESTS();

    return result;
}
