/*
 * Copyright (c) 2020-2026 Valve Corporation
 * Copyright (c) 2020-2026 LunarG, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * This code was generated by Vulkan Configurator 3.5.1
 */

#pragma once

#include <vector>
#include <string>

#include <vulkan/vulkan.hpp>

struct LayerSettings;

// Possible values for `VK_LAYER_LUNARG_reference_1_2_1` layer `enum_required_only` setting:
[[maybe_unused]] static const char* VL_REFERENCE_1_2_1_ENUM_REQUIRED_ONLY_VALUE0 = "value0";
[[maybe_unused]] static const char* VL_REFERENCE_1_2_1_ENUM_REQUIRED_ONLY_VALUE1 = "value1";
[[maybe_unused]] static const char* VL_REFERENCE_1_2_1_ENUM_REQUIRED_ONLY_VALUE2 = "value2";

// Possible values for `VK_LAYER_LUNARG_reference_1_2_1` layer `enum_with_optional` setting:
[[maybe_unused]] static const char* VL_REFERENCE_1_2_1_ENUM_WITH_OPTIONAL_VALUE1 = "value1";
[[maybe_unused]] static const char* VL_REFERENCE_1_2_1_ENUM_WITH_OPTIONAL_VALUE2 = "value2";

// Possible values for VK_LAYER_LUNARG_reference_1_2_1 layer flags_required_only setting:
[[maybe_unused]] static const char* VL_REFERENCE_1_2_1_FLAGS_REQUIRED_ONLY_FLAG0 = "flag0";
[[maybe_unused]] static const char* VL_REFERENCE_1_2_1_FLAGS_REQUIRED_ONLY_FLAG1 = "flag1";
[[maybe_unused]] static const char* VL_REFERENCE_1_2_1_FLAGS_REQUIRED_ONLY_FLAG2 = "flag2";

// Possible values for VK_LAYER_LUNARG_reference_1_2_1 layer flags_with_optional setting:
[[maybe_unused]] static const char* VL_REFERENCE_1_2_1_FLAGS_WITH_OPTIONAL_FLAG0 = "flag0";
[[maybe_unused]] static const char* VL_REFERENCE_1_2_1_FLAGS_WITH_OPTIONAL_FLAG1 = "flag1";

//reference layer
// ==========================================
// VK_LAYER_LUNARG_reference_1_2_1 - 1.4.333 (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
/*
The main, comprehensive Khronos validation layer.

Vulkan is an Explicit API, enabling direct control over how GPUs actually work. By design, minimal error checking is done inside a Vulkan driver. Applications have full control and responsibility for correct operation. Any errors in how Vulkan is used can result in a crash. 

The Khronos Validation Layer can be enabled to assist development by enabling developers to verify their applications correctly use the Vulkan API.
*/
// For more information about the layer: https://vulkan.lunarg.com/doc/sdk/latest/windows/layer_dummy.html
struct Reference121SettingData {
	static const uint32_t VERSION = VK_MAKE_API_VERSION(1, 4, 333, 0);

	// toogle
	// ------------------------------------------
	// toogle (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// true or false
	VkBool32 toogle = VK_TRUE;

	// enum
	// ------------------------------------------
	// enum_required_only (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// enum case
	std::string enum_required_only = VL_REFERENCE_1_2_1_ENUM_REQUIRED_ONLY_VALUE1;

	// enum
	// ------------------------------------------
	// enum_with_optional (BETA) (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// enum case
	// For more information about the feature: https://vulkan.lunarg.com/doc/sdk/latest/windows/layer_dummy.html#enum
	// This setting requires ALL of the following values:
	// - VkBool32 toogle = VK_TRUE;
	std::string enum_with_optional = VL_REFERENCE_1_2_1_ENUM_WITH_OPTIONAL_VALUE1;

	// flags
	// ------------------------------------------
	// flags_required_only (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// flags case
	// This setting can list multiple values using the "," (comma) separator.
	std::vector<std::string> flags_required_only = {VL_REFERENCE_1_2_1_FLAGS_REQUIRED_ONLY_FLAG0, VL_REFERENCE_1_2_1_FLAGS_REQUIRED_ONLY_FLAG1};

	// flags
	// ------------------------------------------
	// flags_with_optional (BETA) (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// flags case
	// This setting can list multiple values using the "," (comma) separator.
	// For more information about the feature: https://vulkan.lunarg.com/doc/sdk/latest/windows/layer_dummy.html#flags
	// This setting requires ALL of the following values:
	// - VkBool32 toogle = VK_TRUE;
	std::vector<std::string> flags_with_optional = {VL_REFERENCE_1_2_1_FLAGS_WITH_OPTIONAL_FLAG0, VL_REFERENCE_1_2_1_FLAGS_WITH_OPTIONAL_FLAG1};

	// String
	// ------------------------------------------
	// string_required_only (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// string
	std::string string_required_only = "A string";

	// String
	// ------------------------------------------
	// string_with_optional (BETA) (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// string
	// For more information about the feature: https://vulkan.lunarg.com/doc/sdk/latest/windows/layer_dummy.html#string
	// This setting requires ALL of the following values:
	// - VkBool32 toogle = VK_TRUE;
	std::string string_with_optional = "A string";

	// bool
	// ------------------------------------------
	// bool_required_only (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// true or false
	VkBool32 bool_required_only = VK_TRUE;

	// bool
	// ------------------------------------------
	// bool_with_optional (BETA) (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// true or false
	// For more information about the feature: https://vulkan.lunarg.com/doc/sdk/latest/windows/layer_dummy.html#bool
	// This setting requires ALL of the following values:
	// - VkBool32 toogle = VK_TRUE;
	VkBool32 bool_with_optional = VK_TRUE;

	// Load file
	// ------------------------------------------
	// load_file_required_only (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// Load file path
	std::string load_file_required_only = "./test.txt";

	// Load file
	// ------------------------------------------
	// load_file_with_optional (BETA) (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// Load file path
	// For more information about the feature: https://vulkan.lunarg.com/doc/sdk/latest/windows/layer_dummy.html#load_file
	// This setting requires ALL of the following values:
	// - VkBool32 toogle = VK_TRUE;
	std::string load_file_with_optional = "./test.json";

	// Save file
	// ------------------------------------------
	// save_file_required_only (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// Save file path
	std::string save_file_required_only = "./test.json";

	// Save file
	// ------------------------------------------
	// save_file_with_optional (BETA) (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// Save file path
	// For more information about the feature: https://vulkan.lunarg.com/doc/sdk/latest/windows/layer_dummy.html#save_file
	// This setting requires ALL of the following values:
	// - VkBool32 toogle = VK_TRUE;
	std::string save_file_with_optional = "./test.json";

	// Save folder
	// ------------------------------------------
	// save_folder_required_only (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// Save folder path
	std::string save_folder_required_only = "./test";

	// Save folder
	// ------------------------------------------
	// save_folder_with_optional (BETA) (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// Save folder path
	// For more information about the feature: https://vulkan.lunarg.com/doc/sdk/latest/windows/layer_dummy.html#save_folder
	// This setting requires ALL of the following values:
	// - VkBool32 toogle = VK_TRUE;
	std::string save_folder_with_optional = "./test";

	// Integer
	// ------------------------------------------
	// int_required_only (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// Integer Description
	int64_t int_required_only = 76;

	// Integer
	// ------------------------------------------
	// int_with_optional (BETA) (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// Integer Description
	// For more information about the feature: https://vulkan.lunarg.com/doc/sdk/latest/windows/layer_dummy.html#int
	// This setting requires ALL of the following values:
	// - VkBool32 toogle = VK_TRUE;
	int64_t int_with_optional = 76;

	// Float
	// ------------------------------------------
	// float_required_only (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// Float Description
	float float_required_only = 76.500000;

	// Float
	// ------------------------------------------
	// float_with_optional (BETA) (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// Float Description
	// For more information about the feature: https://vulkan.lunarg.com/doc/sdk/latest/windows/layer_dummy.html#float
	// This setting requires ALL of the following values:
	// - VkBool32 toogle = VK_TRUE;
	float float_with_optional = 76.500;

	// Frames
	// ------------------------------------------
	// frames_required_only (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// Frames Description
	std::string frames_required_only = "76-82,75";

	// Frames
	// ------------------------------------------
	// frames_with_optional (BETA) (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// Frames Description
	// For more information about the feature: https://vulkan.lunarg.com/doc/sdk/latest/windows/layer_dummy.html#frames
	// This setting requires ALL of the following values:
	// - VkBool32 toogle = VK_TRUE;
	std::string frames_with_optional = "76-82,75";

	// List
	// ------------------------------------------
	// list_required_only (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// List description
	// This setting can list multiple values using the "," (comma) separator.
	std::vector<std::string> list_required_only = {"76", "82", "stringB", "stringC", "stringD"};

	// List
	// ------------------------------------------
	// list_with_optional (BETA) (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// List description
	// This setting can list multiple values using the "," (comma) separator.
	// For more information about the feature: https://vulkan.lunarg.com/doc/sdk/latest/windows/layer_dummy.html#list
	// This setting requires ALL of the following values:
	// - VkBool32 toogle = VK_TRUE;
	std::vector<std::string> list_with_optional = {"76", "82", "stringB", "stringC", "stringD"};

	// List
	// ------------------------------------------
	// list_empty (BETA) (WINDOWS_X86, WINDOWS_ARM, LINUX, ANDROID)
	// List description
	// This setting can list multiple values using the "," (comma) separator.
	// For more information about the feature: https://vulkan.lunarg.com/doc/sdk/latest/windows/layer_dummy.html#list
	std::vector<std::string> list_empty = {};

private:
	friend struct LayerSettings;

	const char* enum_required_only_info = nullptr;
	const char* enum_with_optional_info = nullptr;
	std::vector<const char*> flags_required_only_info;
	std::vector<const char*> flags_with_optional_info;
	const char* string_required_only_info = nullptr;
	const char* string_with_optional_info = nullptr;
	const char* load_file_required_only_info = nullptr;
	const char* load_file_with_optional_info = nullptr;
	const char* save_file_required_only_info = nullptr;
	const char* save_file_with_optional_info = nullptr;
	const char* save_folder_required_only_info = nullptr;
	const char* save_folder_with_optional_info = nullptr;
	const char* frames_required_only_info = nullptr;
	const char* frames_with_optional_info = nullptr;
	std::vector<const char*> list_required_only_info;
	std::vector<const char*> list_with_optional_info;
	std::vector<const char*> list_empty_info;

	void init() {
		this->enum_required_only_info = this->enum_required_only.c_str();
		this->enum_with_optional_info = this->enum_with_optional.c_str();
		this->flags_required_only_info.resize(this->flags_required_only.size());
		for (std::size_t i = 0, n = flags_required_only_info.size(); i < n; ++i) {
			this->flags_required_only_info[i] = this->flags_required_only[i].c_str();
		}
		this->flags_with_optional_info.resize(this->flags_with_optional.size());
		for (std::size_t i = 0, n = flags_with_optional_info.size(); i < n; ++i) {
			this->flags_with_optional_info[i] = this->flags_with_optional[i].c_str();
		}
		this->string_required_only_info = this->string_required_only.c_str();
		this->string_with_optional_info = this->string_with_optional.c_str();
		this->load_file_required_only_info = this->load_file_required_only.c_str();
		this->load_file_with_optional_info = this->load_file_with_optional.c_str();
		this->save_file_required_only_info = this->save_file_required_only.c_str();
		this->save_file_with_optional_info = this->save_file_with_optional.c_str();
		this->save_folder_required_only_info = this->save_folder_required_only.c_str();
		this->save_folder_with_optional_info = this->save_folder_with_optional.c_str();
		this->frames_required_only_info = this->frames_required_only.c_str();
		this->frames_with_optional_info = this->frames_with_optional.c_str();
		this->list_required_only_info.resize(this->list_required_only.size());
		for (std::size_t i = 0, n = list_required_only_info.size(); i < n; ++i) {
			this->list_required_only_info[i] = this->list_required_only[i].c_str();
		}
		this->list_with_optional_info.resize(this->list_with_optional.size());
		for (std::size_t i = 0, n = list_with_optional_info.size(); i < n; ++i) {
			this->list_with_optional_info[i] = this->list_with_optional[i].c_str();
		}
		this->list_empty_info.resize(this->list_empty.size());
		for (std::size_t i = 0, n = list_empty_info.size(); i < n; ++i) {
			this->list_empty_info[i] = this->list_empty[i].c_str();
		}
	}
};

// `LayerSettings` allows initializing layer settings from Vulkan application code.
struct LayerSettings {
	std::vector<std::string> layer_list {
		"VK_LAYER_LUNARG_reference_1_2_1",
	};
	Reference121SettingData reference_1_2_1;

	// Use for VkLayerSettingsCreateInfoEXT `settingCount` and `pSettings` argument
	// Provided by VK_EXT_layer_settings
	// typedef struct VkLayerSettingsCreateInfoEXT {
	// 	VkStructureType             sType;
	// 	const void*                 pNext;
	// 	uint32_t                    settingCount;
	// 	const VkLayerSettingEXT*    pSettings;
	// } VkLayerSettingsCreateInfoEXT;

	std::vector<const char*> layers() {
		std::vector<const char*> results;
		for (std::size_t i = 0, n = layer_list.size(); i < n; ++i) {
			results.push_back(layer_list[i].c_str());
		};
		return results;
	};

	std::vector<vk::LayerSettingEXT> settings() {
		this->reference_1_2_1.init();

		std::vector<vk::LayerSettingEXT> init{
			{"VK_LAYER_LUNARG_reference_1_2_1", "toogle", vk::LayerSettingTypeEXT::eBool32, 1, &this->reference_1_2_1.toogle},
			{"VK_LAYER_LUNARG_reference_1_2_1", "enum_required_only", vk::LayerSettingTypeEXT::eString, 1, this->reference_1_2_1.enum_required_only.c_str()},
			{"VK_LAYER_LUNARG_reference_1_2_1", "enum_with_optional", vk::LayerSettingTypeEXT::eString, 1, this->reference_1_2_1.enum_with_optional.c_str()},
			{"VK_LAYER_LUNARG_reference_1_2_1", "flags_required_only", vk::LayerSettingTypeEXT::eString, static_cast<uint32_t>(this->reference_1_2_1.flags_required_only_info.size()), this->reference_1_2_1.flags_required_only_info.empty() ? nullptr : &this->reference_1_2_1.flags_required_only_info[0]},
			{"VK_LAYER_LUNARG_reference_1_2_1", "flags_with_optional", vk::LayerSettingTypeEXT::eString, static_cast<uint32_t>(this->reference_1_2_1.flags_with_optional_info.size()), this->reference_1_2_1.flags_with_optional_info.empty() ? nullptr : &this->reference_1_2_1.flags_with_optional_info[0]},
			{"VK_LAYER_LUNARG_reference_1_2_1", "string_required_only", vk::LayerSettingTypeEXT::eString, 1, this->reference_1_2_1.string_required_only.c_str()},
			{"VK_LAYER_LUNARG_reference_1_2_1", "string_with_optional", vk::LayerSettingTypeEXT::eString, 1, this->reference_1_2_1.string_with_optional.c_str()},
			{"VK_LAYER_LUNARG_reference_1_2_1", "bool_required_only", vk::LayerSettingTypeEXT::eBool32, 1, &this->reference_1_2_1.bool_required_only},
			{"VK_LAYER_LUNARG_reference_1_2_1", "bool_with_optional", vk::LayerSettingTypeEXT::eBool32, 1, &this->reference_1_2_1.bool_with_optional},
			{"VK_LAYER_LUNARG_reference_1_2_1", "load_file_required_only", vk::LayerSettingTypeEXT::eString, 1, this->reference_1_2_1.load_file_required_only.c_str()},
			{"VK_LAYER_LUNARG_reference_1_2_1", "load_file_with_optional", vk::LayerSettingTypeEXT::eString, 1, this->reference_1_2_1.load_file_with_optional.c_str()},
			{"VK_LAYER_LUNARG_reference_1_2_1", "save_file_required_only", vk::LayerSettingTypeEXT::eString, 1, this->reference_1_2_1.save_file_required_only.c_str()},
			{"VK_LAYER_LUNARG_reference_1_2_1", "save_file_with_optional", vk::LayerSettingTypeEXT::eString, 1, this->reference_1_2_1.save_file_with_optional.c_str()},
			{"VK_LAYER_LUNARG_reference_1_2_1", "save_folder_required_only", vk::LayerSettingTypeEXT::eString, 1, this->reference_1_2_1.save_folder_required_only.c_str()},
			{"VK_LAYER_LUNARG_reference_1_2_1", "save_folder_with_optional", vk::LayerSettingTypeEXT::eString, 1, this->reference_1_2_1.save_folder_with_optional.c_str()},
			{"VK_LAYER_LUNARG_reference_1_2_1", "int_required_only", vk::LayerSettingTypeEXT::eInt64, 1, &this->reference_1_2_1.int_required_only},
			{"VK_LAYER_LUNARG_reference_1_2_1", "int_with_optional", vk::LayerSettingTypeEXT::eInt64, 1, &this->reference_1_2_1.int_with_optional},
			{"VK_LAYER_LUNARG_reference_1_2_1", "float_required_only", vk::LayerSettingTypeEXT::eFloat32, 1, &this->reference_1_2_1.float_required_only},
			{"VK_LAYER_LUNARG_reference_1_2_1", "float_with_optional", vk::LayerSettingTypeEXT::eFloat32, 1, &this->reference_1_2_1.float_with_optional},
			{"VK_LAYER_LUNARG_reference_1_2_1", "frames_required_only", vk::LayerSettingTypeEXT::eUint32, 1, &this->reference_1_2_1.frames_required_only},
			{"VK_LAYER_LUNARG_reference_1_2_1", "frames_with_optional", vk::LayerSettingTypeEXT::eUint32, 1, &this->reference_1_2_1.frames_with_optional},
			{"VK_LAYER_LUNARG_reference_1_2_1", "list_required_only", vk::LayerSettingTypeEXT::eString, static_cast<uint32_t>(this->reference_1_2_1.list_required_only_info.size()), this->reference_1_2_1.list_required_only_info.empty() ? nullptr : &this->reference_1_2_1.list_required_only_info[0]},
			{"VK_LAYER_LUNARG_reference_1_2_1", "list_with_optional", vk::LayerSettingTypeEXT::eString, static_cast<uint32_t>(this->reference_1_2_1.list_with_optional_info.size()), this->reference_1_2_1.list_with_optional_info.empty() ? nullptr : &this->reference_1_2_1.list_with_optional_info[0]},
			{"VK_LAYER_LUNARG_reference_1_2_1", "list_empty", vk::LayerSettingTypeEXT::eString, static_cast<uint32_t>(this->reference_1_2_1.list_empty_info.size()), this->reference_1_2_1.list_empty_info.empty() ? nullptr : &this->reference_1_2_1.list_empty_info[0]},
		};
		return init;
	};
};

