// Copyright 2023 The Khronos Group Inc.
// Copyright 2023 Valve Corporation
// Copyright 2023 LunarG, Inc.
//
// SPDX-License-Identifier: Apache-2.0
//
// Author(s):
// - Christophe Riccio <christophe@lunarg.com>
#include "layer_settings_manager.hpp"
#include "layer_settings_util.hpp"

#include <sys/stat.h>

#if defined(_WIN32)
#include <windows.h>
#include <direct.h>
#define GetCurrentDir _getcwd
#else
#include <unistd.h>
#define GetCurrentDir getcwd
#endif

#ifdef __ANDROID__
#include <sys/system_properties.h>
#endif

#include <cassert>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <array>
#include <algorithm>

#if defined(__ANDROID__)
static std::string GetAndroidProperty(const char *name) {
    std::string output;
    const prop_info *pi = __system_property_find(name);
    if (pi) {
        __system_property_read_callback(
            pi,
            [](void *cookie, const char *name, const char *value, uint32_t serial) {
                (void)name;
                (void)serial;
                reinterpret_cast<std::string *>(cookie)->assign(value);
            },
            reinterpret_cast<void *>(&output));
    }
    return output;
}
#endif

static bool IsEnvironment(const char *variable) {
#if defined(__ANDROID__)
    return !GetAndroidProperty(variable).empty();
#else
    return std::getenv(variable) != NULL;
#endif
}

static std::string GetEnvironment(const char *variable) {
#if defined(__ANDROID__)
    return GetAndroidProperty(variable);
#else
    const char *output = std::getenv(variable);
    return output == NULL ? "" : output;
#endif
}

#if defined(WIN32)
// Check for admin rights
static inline bool IsHighIntegrity() {
    HANDLE process_token;
    if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_QUERY_SOURCE, &process_token)) {
        // Maximum possible size of SID_AND_ATTRIBUTES is maximum size of a SID + size of attributes DWORD.
        uint8_t mandatory_label_buffer[SECURITY_MAX_SID_SIZE + sizeof(DWORD)];
        DWORD buffer_size;
        if (GetTokenInformation(process_token, TokenIntegrityLevel, mandatory_label_buffer, sizeof(mandatory_label_buffer),
                                &buffer_size) != 0) {
            const TOKEN_MANDATORY_LABEL *mandatory_label = (const TOKEN_MANDATORY_LABEL *)mandatory_label_buffer;
            const DWORD sub_authority_count = *GetSidSubAuthorityCount(mandatory_label->Label.Sid);
            const DWORD integrity_level = *GetSidSubAuthority(mandatory_label->Label.Sid, sub_authority_count - 1);

            CloseHandle(process_token);
            return integrity_level > SECURITY_MANDATORY_MEDIUM_RID;
        }

        CloseHandle(process_token);
    }

    return false;
}
#endif

// To prevent exposing an interface that would make it easy to use inconsistent setting naming,
// we hide here workaround of existing layers to preserve backward compatibility
static void AddWorkaroundLayerNames(std::vector<std::string> &layer_names) { 
    if (std::find(layer_names.begin(), layer_names.end(), "VK_LAYER_KHRONOS_synchronization2") != layer_names.end()) {
        layer_names.push_back("VK_LAYER_KHRONOS_sync2");
        return;
    }
}

namespace vl {

LayerSettings::LayerSettings(
    const char *pLayerName,
    uint32_t settingCount, VkLayerSettingPropertiesEXT *pSettings,
    const VkLayerSettingsCreateInfoEXT *pCreateInfo,
    const VkAllocationCallbacks *pAllocator, VL_LAYER_SETTING_LOG_CALLBACK callback)
    : layer_name(pLayerName), create_info(pCreateInfo), callback(callback) {
    (void)pAllocator;
    assert(pLayerName != nullptr);

    this->settings.resize(settingCount);
    memcpy(&this->settings[0], pSettings, sizeof(VkLayerSettingPropertiesEXT) * settingCount);

    std::string settings_file = this->FindSettingsFile();
    this->ParseSettingsFile(settings_file.c_str());
}

LayerSettings::~LayerSettings() {}

void LayerSettings::ParseSettingsFile(const char *filename) {
    // Extract option = value pairs from a file
    std::ifstream file(filename);
    if (file.good()) {
        for (std::string line; std::getline(file, line);) {
            // discard comments, which start with '#'
            const auto comments_pos = line.find_first_of('#');
            if (comments_pos != std::string::npos) line.erase(comments_pos);

            const auto value_pos = line.find_first_of('=');
            if (value_pos != std::string::npos) {
                const std::string setting_key = vl::TrimWhitespace(line.substr(0, value_pos));
                const std::string setting_value = vl::TrimWhitespace(line.substr(value_pos + 1));
                this->setting_file_values[setting_key] = setting_value;
            }
        }
    }
}

std::string LayerSettings::FindSettingsFile() {
    struct stat info;

#if defined(WIN32)
    // Look for VkConfig-specific settings location specified in the windows registry
    HKEY key;

    const std::array<HKEY, 2> hives = {HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER};
    const size_t hives_to_check_count = IsHighIntegrity() ? 1 : hives.size();  // Admin checks only the default hive

    for (size_t hive_index = 0; hive_index < hives_to_check_count; ++hive_index) {
        LSTATUS err = RegOpenKeyEx(hives[hive_index], "Software\\Khronos\\Vulkan\\Settings", 0, KEY_READ, &key);
        if (err == ERROR_SUCCESS) {
            char name[2048];
            DWORD i = 0, name_size, type, pValues, value_size;
            while (ERROR_SUCCESS == RegEnumValue(key, i++, name, &(name_size = sizeof(name)), nullptr, &type,
                                                 reinterpret_cast<LPBYTE>(&pValues), &(value_size = sizeof(pValues)))) {
                // Check if the registry entry is a dword with a value of zero
                if (type != REG_DWORD || pValues != 0) {
                    continue;
                }

                // Check if this actually points to a file
                if ((stat(name, &info) != 0) || !(info.st_mode & S_IFREG)) {
                    continue;
                }

                // Use this file
                RegCloseKey(key);
                return name;
            }

            RegCloseKey(key);
        }
    }
#else
    // Look for VkConfig-specific settings location specified in a specific spot in the linux settings store
    std::string search_path = GetEnvironment("XDG_DATA_HOME");
    if (search_path == "") {
        search_path = GetEnvironment("HOME");
        if (search_path != "") {
            search_path += "/.local/share";
        }
    }
    // Use the vk_layer_settings.txt file from here, if it is present
    if (search_path != "") {
        std::string home_file = search_path + "/vulkan/settings.d/vk_layer_settings.txt";
        if (stat(home_file.c_str(), &info) == 0) {
            if (info.st_mode & S_IFREG) {
                return home_file;
            }
        }
    }
#endif

#ifdef __ANDROID__
    std::string env_path = GetEnvironment("debug.vulkan.khronos_profiles.settings_path");
#else
    // Look for an environment variable override for the settings file location
    std::string env_path = GetEnvironment("VK_LAYER_SETTINGS_PATH");
#endif

    // If the path exists use it, else use vk_layer_settings
    if (stat(env_path.c_str(), &info) == 0) {
        // If this is a directory, append settings file name
        if (info.st_mode & S_IFDIR) {
            env_path.append("/vk_layer_settings.txt");
        }
        return env_path;
    }

    // Default -- use the current working directory for the settings file location
    char buff[512];
    auto buf_ptr = GetCurrentDir(buff, 512);
    if (buf_ptr) {
        std::string location = buf_ptr;
        location.append("/vk_layer_settings.txt");
        return location;
    }
    return "vk_layer_settings.txt";
}

const VkLayerSettingEXT *LayerSettings::FindLayerSettingValue(const char *pSettingName) {
    if (this->create_info == nullptr) {
        return nullptr;
    }

    const std::string setting_name(pSettingName);

    for (std::size_t i = 0, n = this->create_info->settingCount; i < n; ++i) {
        const VkLayerSettingEXT *setting = &this->create_info->pSettings[i];
        if (setting->pLayerName != this->layer_name) {
            continue;
        }

        if (setting->pSettingName != setting_name) {
            continue;
        }

        return setting;
    }

    return nullptr;
}

void LayerSettings::Log(const char *pSettingName, const char * pMessage) {
    this->last_log_setting = pSettingName;
    this->last_log_message = pMessage;

    if (this->callback == nullptr) {
        fprintf(stderr, "LAYER SETTING (%s) error: %s\n", this->last_log_setting.c_str(), this->last_log_message.c_str());
    } else {
        this->callback(this->last_log_setting.c_str(), this->last_log_message.c_str());
    }
}

std::vector<std::string> &LayerSettings::GetSettingCache(const std::string &settingName) {
    if (this->string_setting_cache.find(settingName) != this->string_setting_cache.end()) {
        this->string_setting_cache.insert(
            std::pair<std::string, std::vector<std::string>>(settingName, std::vector<std::string>()));
    }

    return this->string_setting_cache[settingName];
}

bool LayerSettings::HasEnvSetting(const char *pSettingName) {
    assert(pSettingName != nullptr);

    for (int i = TRIM_FIRST, n = TRIM_LAST; i < n; ++i) {
        if (IsEnvironment(GetEnvSettingName(this->layer_name.c_str(), pSettingName, static_cast<TrimMode>(i)).c_str())) {
            return true;
        }
    }

    return false;
}

bool LayerSettings::HasFileSetting(const char *pSettingName) { 
    assert(pSettingName != nullptr);

    std::string file_setting_name = vl::GetFileSettingName(this->layer_name.c_str(), pSettingName);

    return setting_file_values.find(file_setting_name) != setting_file_values.end();
}

bool LayerSettings::HasAPISetting(const char *pSettingName) {
    assert(pSettingName != nullptr);

    return this->FindLayerSettingValue(pSettingName) != nullptr;
}

std::string LayerSettings::GetEnvSetting(const char *pSettingName) {
    std::string result;

    std::vector<std::string> layer_names;
    layer_names.push_back(this->layer_name);
    ::AddWorkaroundLayerNames(layer_names);

    for (std::size_t layer_index = 0, layer_count = layer_names.size(); layer_index < layer_count; ++layer_index) {
        for (int i = TRIM_FIRST, n = TRIM_LAST; i < n; ++i) {
            result = GetEnvironment(GetEnvSettingName(layer_names[layer_index].c_str(), pSettingName, static_cast<TrimMode>(i)).c_str());
            if (!result.empty()) {
                break;
            }
        }
    }

    return result;
}

std::string LayerSettings::GetFileSetting(const char *pSettingName) {
    const std::string file_setting_name = vl::GetFileSettingName(this->layer_name.c_str(), pSettingName);

    std::map<std::string, std::string>::const_iterator it;
    if ((it = this->setting_file_values.find(file_setting_name)) == this->setting_file_values.end()) {
        return "";
    } else {
        return it->second;
    }
}

void LayerSettings::SetFileSetting(const char *pSettingName, const std::string &pValues) {
    assert(pSettingName != nullptr);

    this->setting_file_values.insert({pSettingName, pValues});
}

const VkLayerSettingEXT *LayerSettings::GetAPISetting(const char *pSettingName) { 
    assert(pSettingName != nullptr);

    return reinterpret_cast<const VkLayerSettingEXT *>(this->FindLayerSettingValue(pSettingName));
}

}  // namespace vl
