/*
 * Copyright (c) 2021-2023 The Khronos Group Inc.
 * Copyright (c) 2021-2023 Valve Corporation
 * Copyright (c) 2021-2023 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: Charles Giessen <charles@lunarg.com>
 */

#include "test_util.h"

#if defined(WIN32)
#include <strsafe.h>
const char* win_api_error_str(LSTATUS status) {
    if (status == ERROR_INVALID_FUNCTION) return "ERROR_INVALID_FUNCTION";
    if (status == ERROR_FILE_NOT_FOUND) return "ERROR_FILE_NOT_FOUND";
    if (status == ERROR_PATH_NOT_FOUND) return "ERROR_PATH_NOT_FOUND";
    if (status == ERROR_TOO_MANY_OPEN_FILES) return "ERROR_TOO_MANY_OPEN_FILES";
    if (status == ERROR_ACCESS_DENIED) return "ERROR_ACCESS_DENIED";
    if (status == ERROR_INVALID_HANDLE) return "ERROR_INVALID_HANDLE";
    if (status == ERROR_ENVVAR_NOT_FOUND) return "ERROR_ENVVAR_NOT_FOUND";
    if (status == ERROR_SETENV_FAILED) return "ERROR_SETENV_FAILED";
    return "UNKNOWN ERROR";
}

void print_error_message(LSTATUS status, const char* function_name, std::string optional_message) {
    LPVOID lpMsgBuf;
    DWORD dw = GetLastError();

    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, dw,
                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), reinterpret_cast<LPTSTR>(&lpMsgBuf), 0, nullptr);

    std::cerr << function_name << " failed with " << win_api_error_str(status) << ": "
              << std::string(reinterpret_cast<LPTSTR>(lpMsgBuf));
    if (optional_message != "") {
        std::cerr << " | " << optional_message;
    }
    std::cerr << "\n";
    LocalFree(lpMsgBuf);
}

void EnvVarWrapper::set_env_var() {
    BOOL ret = SetEnvironmentVariableW(widen(name).c_str(), widen(cur_value).c_str());
    if (ret == 0) {
        print_error_message(ERROR_SETENV_FAILED, "SetEnvironmentVariableW");
    }
}
void EnvVarWrapper::remove_env_var() const { SetEnvironmentVariableW(widen(name).c_str(), nullptr); }
std::string get_env_var(std::string const& name, bool report_failure) {
    std::wstring name_utf16 = widen(name);
    DWORD value_size = GetEnvironmentVariableW(name_utf16.c_str(), nullptr, 0);
    if (0 == value_size) {
        if (report_failure) print_error_message(ERROR_ENVVAR_NOT_FOUND, "GetEnvironmentVariableW");
        return {};
    }
    std::wstring value(value_size, L'\0');
    if (GetEnvironmentVariableW(name_utf16.c_str(), &value[0], value_size) != value_size - 1) {
        return {};
    }
    return narrow(value);
}
#elif COMMON_UNIX_PLATFORMS

void EnvVarWrapper::set_env_var() { setenv(name.c_str(), cur_value.c_str(), 1); }
void EnvVarWrapper::remove_env_var() const { unsetenv(name.c_str()); }
std::string get_env_var(std::string const& name, bool report_failure) {
    char* ret = getenv(name.c_str());
    if (ret == nullptr) {
        if (report_failure) std::cerr << "Failed to get environment variable:" << name << "\n";
        return std::string();
    }
    return ret;
}
#endif

template <typename T>
void print_object_of_t(JsonWriter& writer, const char* object_name, std::vector<T> const& vec) {
    if (vec.size() == 0) return;
    writer.StartKeyedObject(object_name);
    for (auto& element : vec) {
        element.get_manifest_str(writer);
    }
    writer.EndObject();
}

template <typename T>
void print_array_of_t(JsonWriter& writer, const char* object_name, std::vector<T> const& vec) {
    if (vec.size() == 0) return;
    writer.StartKeyedArray(object_name);
    for (auto& element : vec) {
        element.get_manifest_str(writer);
    }
    writer.EndArray();
}
void print_vector_of_strings(JsonWriter& writer, const char* object_name, std::vector<std::string> const& strings) {
    if (strings.size() == 0) return;
    writer.StartKeyedArray(object_name);
    for (auto& str : strings) {
        writer.AddString(fs::fixup_backslashes_in_path(str));
    }
    writer.EndArray();
}

std::string to_text(bool b) { return b ? std::string("true") : std::string("false"); }

std::string ManifestICD::get_manifest_str() const {
    JsonWriter writer;
    writer.StartObject();
    writer.AddKeyedString("file_format_version", file_format_version.get_version_str());
    writer.StartKeyedObject("ICD");
    writer.AddKeyedString("library_path", fs::fixup_backslashes_in_path(lib_path).str());
    writer.AddKeyedString("api_version", version_to_string(api_version));
    writer.AddKeyedBool("is_portability_driver", is_portability_driver);
    if (!library_arch.empty()) writer.AddKeyedString("library_arch", library_arch);
    writer.EndObject();
    writer.EndObject();
    return writer.output;
}

void ManifestLayer::LayerDescription::Extension::get_manifest_str(JsonWriter& writer) const {
    writer.StartObject();
    writer.AddKeyedString("name", name);
    writer.AddKeyedString("spec_version", std::to_string(spec_version));
    writer.AddKeyedString("spec_version", std::to_string(spec_version));
    print_vector_of_strings(writer, "entrypoints", entrypoints);
    writer.EndObject();
}

void ManifestLayer::LayerDescription::get_manifest_str(JsonWriter& writer) const {
    writer.AddKeyedString("name", name);
    writer.AddKeyedString("type", get_type_str(type));
    if (!lib_path.str().empty()) {
        writer.AddKeyedString("library_path", fs::fixup_backslashes_in_path(lib_path.str()));
    }
    writer.AddKeyedString("api_version", version_to_string(api_version));
    writer.AddKeyedString("implementation_version", std::to_string(implementation_version));
    writer.AddKeyedString("description", description);
    print_object_of_t(writer, "functions", functions);
    print_array_of_t(writer, "instance_extensions", instance_extensions);
    print_array_of_t(writer, "device_extensions", device_extensions);
    if (!enable_environment.empty()) {
        writer.StartKeyedObject("enable_environment");
        writer.AddKeyedString(enable_environment, "1");
        writer.EndObject();
    }
    if (!disable_environment.empty()) {
        writer.StartKeyedObject("disable_environment");
        writer.AddKeyedString(disable_environment, "1");
        writer.EndObject();
    }
    print_vector_of_strings(writer, "component_layers", component_layers);
    print_vector_of_strings(writer, "blacklisted_layers", blacklisted_layers);
    print_vector_of_strings(writer, "override_paths", override_paths);
    print_vector_of_strings(writer, "app_keys", app_keys);
    print_object_of_t(writer, "pre_instance_functions", pre_instance_functions);
    if (!library_arch.empty()) {
        writer.AddKeyedString("library_arch", library_arch);
    }
}

VkLayerProperties ManifestLayer::LayerDescription::get_layer_properties() const {
    VkLayerProperties properties{};
    copy_string_to_char_array(name, properties.layerName, VK_MAX_EXTENSION_NAME_SIZE);
    copy_string_to_char_array(description, properties.description, VK_MAX_EXTENSION_NAME_SIZE);
    properties.implementationVersion = implementation_version;
    properties.specVersion = api_version;
    return properties;
}

std::string ManifestLayer::get_manifest_str() const {
    JsonWriter writer;
    writer.StartObject();
    writer.AddKeyedString("file_format_version", file_format_version.get_version_str());
    if (layers.size() == 1) {
        writer.StartKeyedObject("layer");
        layers.at(0).get_manifest_str(writer);
        writer.EndObject();
    } else {
        writer.StartKeyedArray("layers");
        for (size_t i = 0; i < layers.size(); i++) {
            writer.StartObject();
            layers.at(i).get_manifest_str(writer);
            writer.EndObject();
        }
        writer.EndArray();
    }
    writer.EndObject();
    return writer.output;
}

namespace fs {
std::string make_native(std::string const& in_path) {
    std::string out;
#if defined(WIN32)
    for (auto& c : in_path) {
        if (c == '/')
            out += "\\";
        else
            out += c;
    }
#elif COMMON_UNIX_PLATFORMS
    for (size_t i = 0; i < in_path.size(); i++) {
        if (i + 1 < in_path.size() && in_path[i] == '\\' && in_path[i + 1] == '\\') {
            out += '/';
            i++;
        } else
            out += in_path[i];
    }
#endif
    return out;
}

// Json doesn't allow `\` in strings, it must be escaped. Thus we have to convert '\\' to '\\\\' in strings
std::string fixup_backslashes_in_path(std::string const& in_path) {
    std::string out;
    for (auto& c : in_path) {
        if (c == '\\')
            out += "\\\\";
        else
            out += c;
    }
    return out;
}
fs::path fixup_backslashes_in_path(fs::path const& in_path) { return fixup_backslashes_in_path(in_path.str()); }

path& path::operator+=(path const& in) {
    contents += in.contents;
    return *this;
}
path& path::operator+=(std::string const& in) {
    contents += in;
    return *this;
}
path& path::operator+=(const char* in) {
    contents += std::string{in};
    return *this;
}
path& path::operator/=(path const& in) {
    if (contents.back() != path_separator && in.contents.front() != path_separator) contents += path_separator;
    contents += in.contents;
    return *this;
}
path& path::operator/=(std::string const& in) {
    if (contents.back() != path_separator && in.front() != path_separator) contents += path_separator;
    contents += in;
    return *this;
}
path& path::operator/=(const char* in) {
    std::string in_str{in};
    if (contents.back() != path_separator && in_str.front() != path_separator) contents += path_separator;
    contents += in_str;
    return *this;
}
path path::operator+(path const& in) const {
    path new_path = contents;
    new_path += in;
    return new_path;
}
path path::operator+(std::string const& in) const {
    path new_path = contents;
    new_path += in;
    return new_path;
}
path path::operator+(const char* in) const {
    path new_path(contents);
    new_path += in;
    return new_path;
}

path path::operator/(path const& in) const {
    path new_path = contents;
    new_path /= in;
    return new_path;
}
path path::operator/(std::string const& in) const {
    path new_path = contents;
    new_path /= in;
    return new_path;
}
path path::operator/(const char* in) const {
    path new_path(contents);
    new_path /= in;
    return new_path;
}

path path::parent_path() const {
    auto last_div = contents.rfind(path_separator);
    if (last_div == std::string::npos) return "";
    return path(contents.substr(0, last_div));
}
bool path::has_parent_path() const {
    auto last_div = contents.rfind(path_separator);
    return last_div != std::string::npos;
}
path path::filename() const {
    auto last_div = contents.rfind(path_separator);
    return path(contents.substr(last_div + 1, contents.size() - last_div + 1));
}

path path::extension() const {
    auto last_div = contents.rfind(path_separator);
    auto ext_div = contents.rfind('.');
    // Make sure to not get the special `.` and `..`, as well as any filename that being with a dot, like .profile
    if (last_div + 1 == ext_div || (last_div + 2 == ext_div && contents[last_div + 1] == '.')) return path("");
    path temp = path(contents.substr(ext_div, contents.size() - ext_div + 1));

    return path(contents.substr(ext_div, contents.size() - ext_div + 1));
}

path path::stem() const {
    auto last_div = contents.rfind(path_separator);
    auto ext_div = contents.rfind('.');
    if (last_div + 1 == ext_div || (last_div + 2 == ext_div && contents[last_div + 1] == '.')) {
        return path(contents.substr(last_div + 1, contents.size() - last_div + 1));
    }
    return path(contents.substr(last_div + 1, ext_div - last_div - 1));
}

path& path::replace_filename(path const& replacement) {
    *this = parent_path() / replacement.str();
    return *this;
}

// internal implementation helper for per-platform creating & destroying folders
int create_folder(path const& path) {
#if defined(WIN32)
    return _wmkdir(widen(path.str()).c_str());
#else
    mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
    return 0;
#endif
}

int delete_folder_contents(path const& folder) {
#if defined(WIN32)
    std::wstring folder_utf16 = widen(folder.str());
    if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW(folder_utf16.c_str()) && GetLastError() == ERROR_FILE_NOT_FOUND) {
        // nothing to delete
        return 0;
    }
    std::wstring search_path = folder_utf16 + L"/*.*";
    std::string s_p = folder.str() + "/";
    WIN32_FIND_DATAW fd;
    HANDLE hFind = ::FindFirstFileW(search_path.c_str(), &fd);
    if (hFind != INVALID_HANDLE_VALUE) {
        do {
            std::string file_name_utf8 = narrow(fd.cFileName);
            if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                if (!string_eq(file_name_utf8.c_str(), ".") && !string_eq(file_name_utf8.c_str(), "..")) {
                    delete_folder(s_p + file_name_utf8);
                }
            } else {
                std::string child_name = s_p + file_name_utf8;
                DeleteFileW(widen(child_name).c_str());
            }
        } while (::FindNextFileW(hFind, &fd));
        ::FindClose(hFind);
    }
    return 0;
#else
    DIR* dir = opendir(folder.c_str());
    if (!dir) {
        return 0;
    }
    int ret = 0;
    dirent* file;
    while (!ret && (file = readdir(dir))) {
        int ret2 = -1;

        /* Skip the names "." and ".." as we don't want to recurse on them. */
        if (string_eq(file->d_name, ".") || string_eq(file->d_name, "..")) continue;

        path file_path = folder / file->d_name;
        struct stat statbuf;
        if (!stat(file_path.c_str(), &statbuf)) {
            if (S_ISDIR(statbuf.st_mode))
                ret2 = delete_folder(file_path);
            else
                ret2 = unlink(file_path.c_str());
        }

        ret = ret2;
    }
    closedir(dir);
    return ret;
#endif
}

int delete_folder(path const& folder) {
    int ret = delete_folder_contents(folder);
    if (ret != 0) return ret;
#if defined(WIN32)
    _wrmdir(widen(folder.str()).c_str());
    return 0;
#else
    return rmdir(folder.c_str());
#endif
}

#if defined(WIN32)
std::wstring native_path(const std::string& utf8) { return widen(utf8); }
#else
const std::string& native_path(const std::string& utf8) { return utf8; }
#endif

FolderManager::FolderManager(path root_path, std::string name) noexcept : folder(root_path / name) {
    delete_folder_contents(folder);
    create_folder(folder);
}
FolderManager::~FolderManager() noexcept {
    if (folder.str().empty()) return;
    auto list_of_files_to_delete = files;
    // remove(file) modifies the files variable, copy the list before deleting it
    // Note: the allocation tests currently leak the loaded driver handles because in an OOM scenario the loader doesn't bother
    // removing those. Since this is in an OOM situation, it is a low priority to fix. It does have the effect that Windows will
    // be unable to delete the binaries that were leaked.
    for (auto& file : list_of_files_to_delete) {
        remove(file);
    }
    delete_folder(folder);
}
FolderManager::FolderManager(FolderManager&& other) noexcept : folder(other.folder), files(other.files) {
    other.folder.str().clear();
}
FolderManager& FolderManager::operator=(FolderManager&& other) noexcept {
    folder = other.folder;
    files = other.files;
    other.folder.str().clear();
    return *this;
}

path FolderManager::write_manifest(std::string const& name, std::string const& contents) {
    path out_path = folder / name;
    auto found = std::find(files.begin(), files.end(), name);
    if (found != files.end()) {
        std::cout << "Overwriting manifest " << name << ". Was this intended?\n";
    } else {
        files.emplace_back(name);
    }
    auto file = std::ofstream(native_path(out_path.str()), std::ios_base::trunc | std::ios_base::out);
    if (!file) {
        std::cerr << "Failed to create manifest " << name << " at " << out_path.str() << "\n";
        return out_path;
    }
    file << contents << std::endl;
    return out_path;
}
void FolderManager::add_existing_file(std::string const& file_name) { files.emplace_back(file_name); }

// close file handle, delete file, remove `name` from managed file list.
void FolderManager::remove(std::string const& name) {
    path out_path = folder / name;
    auto found = std::find(files.begin(), files.end(), name);
    if (found != files.end()) {
        int rc = std::remove(out_path.c_str());
        if (rc != 0) {
            std::cerr << "Failed to remove file " << name << " at " << out_path.str() << "\n";
        }

        files.erase(found);

    } else {
        std::cout << "Couldn't remove file " << name << " at " << out_path.str() << ".\n";
    }
}

// copy file into this folder
path FolderManager::copy_file(path const& file, std::string const& new_name) {
    auto new_filepath = folder / new_name;
    auto found = std::find(files.begin(), files.end(), new_name);
    if (found != files.end()) {
        std::cout << "File location already contains" << new_name << ". Is this a bug?\n";
    } else if (file.str() == new_filepath.str()) {
        std::cout << "Trying to copy " << new_name << " into itself. Is this a bug?\n";
    } else {
        files.emplace_back(new_name);
    }
    std::ifstream src(native_path(file.str()), std::ios::binary);
    if (!src) {
        std::cerr << "Failed to create file " << file.str() << " for copying from\n";
        return new_filepath;
    }
    std::ofstream dst(native_path(new_filepath.str()), std::ios::binary);
    if (!dst) {
        std::cerr << "Failed to create file " << new_filepath.str() << " for copying to\n";
        return new_filepath;
    }
    dst << src.rdbuf();
    return new_filepath;
}
}  // namespace fs

const char* get_platform_wsi_extension([[maybe_unused]] const char* api_selection) {
#if defined(VK_USE_PLATFORM_ANDROID_KHR)
    return "VK_KHR_android_surface";
#elif defined(VK_USE_PLATFORM_DIRECTFB_EXT)
    return "VK_EXT_directfb_surface";
#elif defined(VK_USE_PLATFORM_FUCHSIA)
    return "VK_FUCHSIA_imagepipe_surface";
#elif defined(VK_USE_PLATFORM_GGP)
    return "VK_GGP_stream_descriptor_surface";
#elif defined(VK_USE_PLATFORM_IOS_MVK)
    return "VK_MVK_ios_surface";
#elif defined(VK_USE_PLATFORM_MACOS_MVK) || defined(VK_USE_PLATFORM_METAL_EXT)
#if defined(VK_USE_PLATFORM_MACOS_MVK)
    if (string_eq(api_selection, "VK_USE_PLATFORM_MACOS_MVK")) return "VK_MVK_macos_surface";
#endif
#if defined(VK_USE_PLATFORM_METAL_EXT)
    if (string_eq(api_selection, "VK_USE_PLATFORM_METAL_EXT")) return "VK_EXT_metal_surface";
    return "VK_EXT_metal_surface";
#endif
#elif defined(VK_USE_PLATFORM_SCREEN_QNX)
    return "VK_QNX_screen_surface";
#elif defined(VK_USE_PLATFORM_VI_NN)
    return "VK_NN_vi_surface";
#elif defined(VK_USE_PLATFORM_XCB_KHR) || defined(VK_USE_PLATFORM_XLIB_KHR) || defined(VK_USE_PLATFORM_WAYLAND_KHR)
#if defined(VK_USE_PLATFORM_XCB_KHR)
    if (string_eq(api_selection, "VK_USE_PLATFORM_XCB_KHR")) return "VK_KHR_xcb_surface";
#endif
#if defined(VK_USE_PLATFORM_XLIB_KHR)
    if (string_eq(api_selection, "VK_USE_PLATFORM_XLIB_KHR")) return "VK_KHR_xlib_surface";
#endif
#if defined(VK_USE_PLATFORM_WAYLAND_KHR)
    if (string_eq(api_selection, "VK_USE_PLATFORM_WAYLAND_KHR")) return "VK_KHR_wayland_surface";
#endif
#if defined(VK_USE_PLATFORM_XCB_KHR)
    return "VK_KHR_xcb_surface";
#endif
#elif defined(VK_USE_PLATFORM_WIN32_KHR)
    return "VK_KHR_win32_surface";
#else
    return "VK_KHR_display";
#endif
}

bool string_eq(const char* a, const char* b) noexcept { return a && b && strcmp(a, b) == 0; }
bool string_eq(const char* a, const char* b, size_t len) noexcept { return a && b && strncmp(a, b, len) == 0; }

InstanceCreateInfo::InstanceCreateInfo() {
    instance_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    application_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
}

VkInstanceCreateInfo* InstanceCreateInfo::get() noexcept {
    if (fill_in_application_info) {
        application_info.pApplicationName = app_name.c_str();
        application_info.pEngineName = engine_name.c_str();
        application_info.applicationVersion = app_version;
        application_info.engineVersion = engine_version;
        application_info.apiVersion = api_version;
        instance_info.pApplicationInfo = &application_info;
    }
    instance_info.flags = flags;
    instance_info.enabledLayerCount = static_cast<uint32_t>(enabled_layers.size());
    instance_info.ppEnabledLayerNames = enabled_layers.data();
    instance_info.enabledExtensionCount = static_cast<uint32_t>(enabled_extensions.size());
    instance_info.ppEnabledExtensionNames = enabled_extensions.data();
    return &instance_info;
}
InstanceCreateInfo& InstanceCreateInfo::set_api_version(uint32_t major, uint32_t minor, uint32_t patch) {
    this->api_version = VK_MAKE_API_VERSION(0, major, minor, patch);
    return *this;
}
InstanceCreateInfo& InstanceCreateInfo::setup_WSI(const char* api_selection) {
    add_extensions({"VK_KHR_surface", get_platform_wsi_extension(api_selection)});
    return *this;
}

DeviceQueueCreateInfo::DeviceQueueCreateInfo() { queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO; }
DeviceQueueCreateInfo::DeviceQueueCreateInfo(const VkDeviceQueueCreateInfo* create_info) {
    queue_create_info = *create_info;
    for (uint32_t i = 0; i < create_info->queueCount; i++) {
        priorities.push_back(create_info->pQueuePriorities[i]);
    }
}

VkDeviceQueueCreateInfo DeviceQueueCreateInfo::get() noexcept {
    queue_create_info.pQueuePriorities = priorities.data();
    queue_create_info.queueCount = 1;
    queue_create_info.sType = VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO;
    return queue_create_info;
}

DeviceCreateInfo::DeviceCreateInfo(const VkDeviceCreateInfo* create_info) {
    dev = *create_info;
    for (uint32_t i = 0; i < create_info->enabledExtensionCount; i++) {
        enabled_extensions.push_back(create_info->ppEnabledExtensionNames[i]);
    }
    for (uint32_t i = 0; i < create_info->enabledLayerCount; i++) {
        enabled_layers.push_back(create_info->ppEnabledLayerNames[i]);
    }
    for (uint32_t i = 0; i < create_info->queueCreateInfoCount; i++) {
        device_queue_infos.push_back(create_info->pQueueCreateInfos[i]);
    }
}

VkDeviceCreateInfo* DeviceCreateInfo::get() noexcept {
    dev.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO;
    dev.enabledLayerCount = static_cast<uint32_t>(enabled_layers.size());
    dev.ppEnabledLayerNames = enabled_layers.data();
    dev.enabledExtensionCount = static_cast<uint32_t>(enabled_extensions.size());
    dev.ppEnabledExtensionNames = enabled_extensions.data();
    uint32_t index = 0;
    for (auto& queue : queue_info_details) {
        queue.queue_create_info.queueFamilyIndex = index++;
        queue.queue_create_info.queueCount = 1;
        device_queue_infos.push_back(queue.get());
    }

    dev.queueCreateInfoCount = static_cast<uint32_t>(device_queue_infos.size());
    dev.pQueueCreateInfos = device_queue_infos.data();
    return &dev;
}

#if defined(WIN32)
std::string narrow(const std::wstring& utf16) {
    if (utf16.empty()) {
        return {};
    }
    int size = WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.size()), nullptr, 0, nullptr, nullptr);
    if (size <= 0) {
        return {};
    }
    std::string utf8(size, '\0');
    if (WideCharToMultiByte(CP_UTF8, 0, utf16.data(), static_cast<int>(utf16.size()), &utf8[0], size, nullptr, nullptr) != size) {
        return {};
    }
    return utf8;
}

std::wstring widen(const std::string& utf8) {
    if (utf8.empty()) {
        return {};
    }
    int size = MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast<int>(utf8.size()), nullptr, 0);
    if (size <= 0) {
        return {};
    }
    std::wstring utf16(size, L'\0');
    if (MultiByteToWideChar(CP_UTF8, 0, utf8.data(), static_cast<int>(utf8.size()), &utf16[0], size) != size) {
        return {};
    }
    return utf16;
}
#endif
