#include "KMBuilderConfigJson.h"
#include "KMBuilderConfigYaml.h"
#include "KMBuilderContext.h"
#include "common/KMLogger.h"

#include <filesystem>
#include <fstream>

namespace fs = std::filesystem;

KMBuilderConfigYaml::KMBuilderConfigYaml() { }

KMBuilderConfigYaml::~KMBuilderConfigYaml() { }

bool KMBuilderConfigYaml::loadConfigFile(const string &configFile)
{
    if (configFile.substr(configFile.length() - 5, 5) != ".yaml" && configFile.substr(configFile.length() - 4, 4) != ".yml")
    {
        return false;
    }

    if (!fs::exists(configFile))
    {
        km_logger.error("config file %s not exist!\n", configFile.c_str());
        return false;
    }

    if (configFile.length() <= 4)
    {
        km_logger.error("config file name %s too short!\n", configFile.c_str());
        return false;
    }

    try
    {
        m_rootNode = YAML::LoadFile(configFile);
    }
    catch (...)
    {
        printf("YAML load file error %s\n", configFile.c_str());
        return false;
    }

    this->m_configFile = fs::absolute(configFile);
    this->m_configPath = fs::path(this->m_configFile).parent_path().string();
    return loadBase();
}

any KMBuilderConfigYaml::getAttribute(const string &name)
{
    return m_configData->attributeMap.find(name) == m_configData->attributeMap.end() ? any() : m_configData->attributeMap[name];
}

bool KMBuilderConfigYaml::loadBase()
{
    m_configData->attributeMap.clear();

    m_configData->attributeMap["app-id"] = getString(m_rootNode, "app-id");
    m_configData->attributeMap["id"] = getString(m_rootNode, "id");
    m_configData->attributeMap["id-platform"] = getString(m_rootNode, "id-platform");
    m_configData->attributeMap["branch"] = getString(m_rootNode, "branch");
    m_configData->attributeMap["default-branch"] = getString(m_rootNode, "default-branch");
    m_configData->attributeMap["runtime"] = getString(m_rootNode, "runtime");
    m_configData->attributeMap["runtime-commit"] = getString(m_rootNode, "runtime-commit");
    m_configData->attributeMap["runtime-version"] = getString(m_rootNode, "runtime-version");

    if (getString(m_rootNode, "sdk") == "")
        return false;
    m_configData->attributeMap["sdk"] = getString(m_rootNode, "sdk");
    m_configData->attributeMap["sdk-commit"] = getString(m_rootNode, "sdk-commit");
    m_configData->attributeMap["sdk-version"] = getString(m_rootNode, "sdk-version");
    m_configData->attributeMap["base"] = getString(m_rootNode, "base");
    m_configData->attributeMap["base-commit"] = getString(m_rootNode, "base-commit");
    m_configData->attributeMap["base-version"] = getString(m_rootNode, "base-version");
    m_configData->attributeMap["var"] = getString(m_rootNode, "var");
    m_configData->attributeMap["metadata"] = getString(m_rootNode, "metadata");
    m_configData->attributeMap["metadata-platform"] = getString(m_rootNode, "metadata-platform");
    m_configData->attributeMap["command"] = getString(m_rootNode, "command");
    m_configData->attributeMap["rename-desktop-file"] = getString(m_rootNode, "rename-desktop-file");
    m_configData->attributeMap["desktop-file-name-prefix"] = getString(m_rootNode, "desktop-file-name-prefix");
    m_configData->attributeMap["desktop-file-name-suffix"] = getString(m_rootNode, "desktop-file-name-suffix");
    m_configData->attributeMap["rename-appdata-file"] = getString(m_rootNode, "rename-appdata-file");
    m_configData->attributeMap["appdata-license"] = getString(m_rootNode, "appdata-license");
    m_configData->attributeMap["rename-icon"] = getString(m_rootNode, "rename-icon");
    m_configData->attributeMap["collection-id"] = getString(m_rootNode, "collection-id");
    m_configData->attributeMap["extension-tag"] = getString(m_rootNode, "extension-tag");
    m_configData->attributeMap["build-runtime"] = getBool(m_rootNode, "build-runtime");
    m_configData->attributeMap["build-extension"] = getBool(m_rootNode, "build-extension");
    m_configData->attributeMap["separate-locales"] = getBool(m_rootNode, "separate-locales");
    m_configData->attributeMap["writable-sdk"] = getBool(m_rootNode, "writable-sdk");
    m_configData->attributeMap["appstream-compose"] = getBool(m_rootNode, "appstream-compose");
    m_configData->attributeMap["copy-icon"] = getBool(m_rootNode, "copy-icon");

    m_configData->baseExtensions = getStringArray(m_rootNode, "base-extensions");
    // m_configData->buildOptions               = getStringArray(m_rootNode, "build-options");
    m_configData->cleanup = getStringArray(m_rootNode, "cleanup");
    m_configData->cleanupCommands = getStringArray(m_rootNode, "cleanup-commands");
    m_configData->cleanupPlatform = getStringArray(m_rootNode, "cleanup-platform");
    m_configData->cleanupPlatformCommands = getStringArray(m_rootNode, "cleanup-platform-commands");
    m_configData->preparePlatformCommands = getStringArray(m_rootNode, "prepare-platform-commands");
    m_configData->finishArgs = getStringArray(m_rootNode, "finish-args");
    m_configData->inheritExtensions = getStringArray(m_rootNode, "inherit-extensions");
    m_configData->inheritSdkExtensions = getStringArray(m_rootNode, "inherit-sdk-extensions");
    m_configData->sdkExtensions = getStringArray(m_rootNode, "sdk-extensions");
    m_configData->platformExtensions = getStringArray(m_rootNode, "platform-extensions");
    m_configData->tags = getStringArray(m_rootNode, "tags");

    m_configData->buildOptions = getBuildOptions(m_rootNode["build-options"]);

    std::string saved_demarshalBaseDir = demarshalBaseDir();
    std::string demarshalBaseDir = KMBuilderUtils::buildFilename(saved_demarshalBaseDir, fs::path(this->m_configFile).parent_path().string());
    setDemarshalBaseDir(demarshalBaseDir);
    m_modules = getNodeModules(m_rootNode);
    // fs::current_path(m_configPath);
    setDemarshalBaseDir(saved_demarshalBaseDir);
    loadAddExtensions();
    loadAddBuildExtensions();

    return true;
}

shared_ptr<KMBuildOptions> KMBuilderConfigYaml::getBuildOptions(const YAML::Node &node)
{
    shared_ptr<KMBuildOptions> buildOptions = make_shared<KMBuildOptions>();

    if (!node.IsDefined())
        return buildOptions;

    buildOptions->m_strip = getBool(node, "strip");
    buildOptions->m_noDebuginfo = getBool(node, "no-debuginfo");
    buildOptions->m_noDebuginfoCompression = getBool(node, "no-debuginfo-compression");
    buildOptions->m_cFlags = getString(node, "cflags");
    buildOptions->m_cflagsOverride = getBool(node, "cflags-override");
    buildOptions->m_cppFlags = getString(node, "cppflags");
    buildOptions->m_cppFlagsOverride = getBool(node, "cppflags-override");
    buildOptions->m_cxxFlags = getString(node, "cxxflags");
    buildOptions->m_cxxFlagsOverride = getBool(node, "cxxflags-override");
    buildOptions->m_ldFlags = getString(node, "ldflags");
    buildOptions->m_ldFlagsOverride = getBool(node, "ldflags-override");
    buildOptions->m_appendPath = getString(node, "append-path");
    buildOptions->m_prependPath = getString(node, "prepend-path");
    buildOptions->m_appendLdLibraryPath = getString(node, "append-ld-library-path");
    buildOptions->m_prependLdLibraryPath = getString(node, "prepend-ld-library-path");
    buildOptions->m_appendPkgConfigPath = getString(node, "append-pkg-config-path");
    buildOptions->m_prependPkgConfigPath = getString(node, "prepend-pkg-config-path");
    buildOptions->m_prefix = getString(node, "prefix");
    buildOptions->m_libDir = getString(node, "libdir");
    buildOptions->m_buildArgs = getStringArray(node, "build-args");
    buildOptions->m_testArgs = getStringArray(node, "test-args");
    buildOptions->m_configOpts = getStringArray(node, "config-opts");
    buildOptions->m_secretOpts = getStringArray(node, "secret-opts");
    buildOptions->m_makeArgs = getStringArray(node, "make-args");
    buildOptions->m_makeInstallArgs = getStringArray(node, "make-install-args");

    YAML::Node envNode = node["env"];
    if (envNode.IsDefined() && envNode.Type() == YAML::NodeType::Map)
    {
        for (YAML::Node::const_iterator iter = envNode.begin(); iter != envNode.end(); iter++)
        {
            buildOptions->m_env[iter->first.as<string>()] = getString(envNode, iter->first.as<string>());
        }
    }

    YAML::Node secretEnvNode = node["secret-env"];
    if (secretEnvNode.IsDefined() && secretEnvNode.Type() == YAML::NodeType::Map)
    {
        for (YAML::Node::const_iterator iter = secretEnvNode.begin(); iter != secretEnvNode.end(); iter++)
        {
            buildOptions->m_secretEnv[iter->first.as<string>()] = getString(secretEnvNode, iter->first.as<string>());
        }
    }

    return buildOptions;
}

void KMBuilderConfigYaml::loadAddExtensions()
{
    YAML::Node node = m_rootNode["add-extensions"];
    if (!node.IsDefined() || node.Type() != YAML::NodeType::Map)
        return;

    for (YAML::Node::const_iterator iter = node.begin(); iter != node.end(); iter++)
    {
        m_configData->addExtensions[iter->first.as<string>()] = getExtension(iter->second);
    }
}

void KMBuilderConfigYaml::loadAddBuildExtensions()
{
    YAML::Node node = m_rootNode["add-build-extensions"];
    if (!node.IsDefined() || node.Type() != YAML::NodeType::Map)
        return;

    for (YAML::Node::const_iterator iter = node.begin(); iter != node.end(); iter++)
    {
        m_configData->addBuildExtensions[iter->first.as<string>()] = getExtension(iter->second);
    }
}

const shared_ptr<BuilderExtension> KMBuilderConfigYaml::getExtension(const YAML::Node &node)
{
    shared_ptr<BuilderExtension> ext = make_shared<BuilderExtension>();

    ext->name = getString(node, "name");
    ext->directory = getString(node, "directory");
    ext->bundle = getBool(node, "bundle");
    ext->removeAfterBuild = getBool(node, "remove-after-build");
    ext->autodelete = getBool(node, "autodelete");
    ext->noAutoDownload = getBool(node, "no-autodownload");
    ext->localeSubset = getBool(node, "locale-subset");
    ext->subdirectories = getBool(node, "subdirectories");
    ext->addLdPath = getString(node, "add-ld-path");
    ext->downloadIf = getString(node, "download-if");
    ext->enableIf = getString(node, "enable-if");
    ext->version = getString(node, "version");
    ext->subdirectorySuffix = getString(node, "subdirectory-suffix");

    string str_merge_dirs = getString(node, "merge-dirs");
    ext->mergeDirs = KMBuilderUtils::split(str_merge_dirs, ';');

    string str_versions = getString(node, "versions");
    ext->versions = KMBuilderUtils::split(str_versions, ';');

    return ext;
}

Json::Value parseJsonFile(const std::string &filepath)
{
    Json::Value root;                                    // 将要返回的Json::Value对象
    std::ifstream file(filepath, std::ifstream::binary); // 打开文件

    if (!file.is_open())
    {
        std::cerr << "Error opening file: " << filepath << std::endl;
        return root;
    }

    file >> root; // 读取文件内容到root
    file.close(); // 关闭文件
    return root;
}

const vector<shared_ptr<KMBuilderModule>> KMBuilderConfigYaml::getNodeModules(const YAML::Node &node)
{
    vector<shared_ptr<KMBuilderModule>> modules;
    // sharedModule 使用
    KMBuilderConfigJson parse_json;
    parse_json.setConfigPath(m_configPath);

    YAML::Node modulesNode = node["modules"];
    if (!modulesNode.IsDefined())
        return modules;
    if (modulesNode.Type() == YAML::NodeType::Sequence)
    {
        for (YAML::Node::const_iterator iter = modulesNode.begin(); iter != modulesNode.end(); iter++)
        {
            if ((*iter).IsScalar())
            {
                string sharedModule = (*iter).as<string>();
                if (sharedModule.substr(sharedModule.length() - 5, sharedModule.length()) == ".json")
                {
                    // fs::current_path(m_configPath);
                    parse_json.setDemarshalBaseDir(demarshalBaseDir());
                    m_modules.push_back(parse_json.getSharedModule(sharedModule));
                    continue;
                }
            }
            // 添加一个 module
            shared_ptr<KMBuilderModule> builderModule = make_shared<KMBuilderModule>();
            builderModule->setProperty(KMBuilderModule::Module_Name, getString(*iter, "name"));
            builderModule->setProperty(KMBuilderModule::Module_Subdir, getString(*iter, "subdir"));
            builderModule->setProperty(KMBuilderModule::Module_RmConfigure, getBool(*iter, "rm-configure"));
            builderModule->setProperty(KMBuilderModule::Module_Disable, getBool(*iter, "disabled"));
            builderModule->setProperty(KMBuilderModule::Module_NoAutogen, getBool(*iter, "no-autogen"));
            builderModule->setProperty(KMBuilderModule::Module_NoParallelMake, getBool(*iter, "no-parallel-make"));
            builderModule->setProperty(KMBuilderModule::Module_NoMakeInstall, getBool(*iter, "no-make-install"));
            builderModule->setProperty(KMBuilderModule::Module_NoPythonTimestampFix, getBool(*iter, "no-python-timestamp-fix"));
            builderModule->setProperty(KMBuilderModule::Module_Cmake, getBool(*iter, "cmake"));

            string buildSystem = getString(*iter, "buildsystem");
            builderModule->setBuildSystem(buildSystem);

            builderModule->setProperty(KMBuilderModule::Module_InstallRule, getString(*iter, "install-rule"));
            builderModule->setProperty(KMBuilderModule::Module_TestRule, getString(*iter, "test-rule"));
            builderModule->setProperty(KMBuilderModule::Module_Builddir, getBool(*iter, "builddir"));

            // sources
            std::string saved_demarshalBaseDir = demarshalBaseDir();
            YAML::Node sourcesNode = (*iter)["sources"];
            if (sourcesNode.IsDefined() && sourcesNode.Type() == YAML::NodeType::Sequence)
            {
                for (YAML::Node::const_iterator source_iter = sourcesNode.begin(); source_iter != sourcesNode.end(); source_iter++)
                {
                    vector<shared_ptr<KMBuilderSource>> buildSources;
                    for (int i_source = 0; i_source < sourcesNode.size(); i_source++)
                    {
                        if (sourcesNode[i_source].IsScalar())
                        {
                            string sharedModule = sourcesNode[i_source].as<string>();

                            if (sharedModule.size() < 5)
                                continue;
                            if (sharedModule.substr(sharedModule.length() - 5, sharedModule.length()) == ".json")
                            {
                                Json::Value child_value = parseJsonFile(sharedModule);

                                prasejsonNode(child_value, builderModule, m_configPath, saved_demarshalBaseDir);
                            }
                            continue;
                        }
                        string source_type = getString(sourcesNode[i_source], "type");
                        if (source_type == "archive")
                        {
                            shared_ptr<KMBuilderSourceArchive> sourceArchive = make_shared<KMBuilderSourceArchive>();

                            sourceArchive->setBaseDir(saved_demarshalBaseDir);
                            // sourceArchive->setPath(getString(sourcesNode[i_source], "path"));
                            // sourceArchive->setUrl(getString(sourcesNode[i_source], "url"));
                            // sourceArchive->setMd5(getString(sourcesNode[i_source], "md5"));
                            // sourceArchive->setSha1(getString(sourcesNode[i_source], "sha1"));
                            // sourceArchive->setSha256(getString(sourcesNode[i_source], "sha256"));
                            // sourceArchive->setSha512(getString(sourcesNode[i_source], "sha512"));

                            // // 设置下载路径
                            // string downloadFilename = getString(sourcesNode[i_source], "dest-filename") != "" ? getString(sourcesNode[i_source], "dest-filename") : sourceArchive->getUrl().substr(sourceArchive->getUrl().find_last_of("/") + 1);
                            // sourceArchive->setDestFilename(fs::path(m_configPath) / STATE_DIR / "downloads" / sourceArchive->getChecksum() / downloadFilename);

                            // if (getString(sourcesNode[i_source], "strip-components") != "")
                            //     sourceArchive->setStripComponents(atoi(getString(sourcesNode[i_source], "strip-components").c_str()));
                            // sourceArchive->setGitInit(getBool(sourcesNode[i_source], "git-init"));
                            // sourceArchive->setArchiveType(getString(sourcesNode[i_source], "archive-type"));
                            buildSources.push_back(sourceArchive);
                        }
                        else if (source_type == "dir")
                        {
                            shared_ptr<KMBuilderSourceDir> sourceDir = make_shared<KMBuilderSourceDir>();
                            sourceDir->setBaseDir(saved_demarshalBaseDir);
                            // sourceDir->setPath(getString(sourcesNode[i_source], "path"));
                            // sourceDir->setUrl(getString(sourcesNode[i_source], "url"));
                            // sourceDir->setMirrorUrls(getString(sourcesNode[i_source], "mirrorurl"));
                            // sourceDir->setMd5(getString(sourcesNode[i_source], "md5"));
                            // sourceDir->setSha1(getString(sourcesNode[i_source], "sha1"));
                            // sourceDir->setSha256(getString(sourcesNode[i_source], "sha256"));
                            // sourceDir->setSha512(getString(sourcesNode[i_source], "sha512"));
                            // if (getString(sourcesNode[i_source], "strip-components") != "")
                            // {
                            //     sourceDir->setStripComponents(atoi(getString(sourcesNode[i_source], "strip-components").c_str()));
                            // }
                            // sourceDir->setDestFilename(getString(sourcesNode[i_source], "dest-filename"));
                            // sourceDir->setMirrorUrls(getString(sourcesNode[i_source], "mirror-urls")); // 暂时设置为 string 类型，具体类型需要参考配置文件
                            buildSources.push_back(sourceDir);
                        }
                        else if (source_type == "file")
                        {
                            shared_ptr<KMBuilderSourceFile> sourceFile = make_shared<KMBuilderSourceFile>();
                            sourceFile->setBaseDir(saved_demarshalBaseDir);
                            // sourceFile->setPath(getString(sourcesNode[i_source], "path"));
                            // sourceFile->setUrl(getString(sourcesNode[i_source], "url"));
                            // sourceFile->setMirrorUrls("mirror-urls");
                            // sourceFile->setMd5(getString(sourcesNode[i_source], "md5"));
                            // sourceFile->setSha1(getString(sourcesNode[i_source], "sha1"));
                            // sourceFile->setSha256(getString(sourcesNode[i_source], "sha256"));
                            // sourceFile->setSha512(getString(sourcesNode[i_source], "sha512"));
                            // sourceFile->setStripComponents(atoi(getString(sourcesNode[i_source], "strip-components").c_str()));
                            // sourceFile->setDestFilename(getString(sourcesNode[i_source], "dest-filename"));
                            // sourceFile->setMirrorUrls(getString(sourcesNode[i_source], "mirror-urls")); // 暂时设置为 string 类型，具体类型需要参考配置文件
                            buildSources.push_back(sourceFile);
                        }
                        else if (source_type == "git")
                        {
                            shared_ptr<KMBuilderSourceGit> sourceGit = make_shared<KMBuilderSourceGit>();
                            sourceGit->setBaseDir(saved_demarshalBaseDir);
                            // sourceGit->setUrl(getString(sourcesNode[i_source], "url"));
                            // sourceGit->setPath(getString(sourcesNode[i_source], "path"));
                            // sourceGit->setBranch(getString(sourcesNode[i_source], "branch"));
                            // sourceGit->setTag(getString(sourcesNode[i_source], "tag"));
                            // sourceGit->setCommit(getString(sourcesNode[i_source], "commit"));

                            // sourceGit->setDisableFsckeobjects(getBool(sourcesNode[i_source], "disable-fsckobjects"));
                            // sourceGit->setDisableShallowClone(getBool(sourcesNode[i_source], "disable-shallow-clone"));
                            // sourceGit->setDisableSubmodules(getBool(sourcesNode[i_source], "disable-submodules"));
                            buildSources.push_back(sourceGit);
                            //  builderModule->addBuildSource(sourceGit);
                        }
                        else if (source_type == "script")
                        {
                            shared_ptr<KMBuilderSourceScript> sourceScript = make_shared<KMBuilderSourceScript>();
                            sourceScript->setBaseDir(saved_demarshalBaseDir);
                            // vector<string> commands;
                            // YAML::Node commands_node = sourcesNode[i_source]["commands"];
                            // if (commands_node && commands_node.IsSequence())
                            // {
                            //     for (auto iter = commands_node.begin(); iter != commands_node.end(); ++iter)
                            //     {
                            //         string temp = iter->as<string>();
                            //         commands.push_back(temp);
                            //     }
                            // }
                            // sourceScript->setCommands(commands);
                            // sourceScript->setDestFilename(getString(sourcesNode[i_source], "dest-filename"));
                            buildSources.push_back(sourceScript);
                        }
                        else if (source_type == "shell")
                        {
                            shared_ptr<KMBuilderSourceShell> sourceShell = make_shared<KMBuilderSourceShell>();
                            sourceShell->setBaseDir(saved_demarshalBaseDir);
                            buildSources.push_back(sourceShell);
                        }
                        else if (source_type == "svn")
                        {
                            shared_ptr<KMBuilderSourceSvn> sourceSvn = make_shared<KMBuilderSourceSvn>();
                            sourceSvn->setBaseDir(saved_demarshalBaseDir);
                            // sourceSvn->setUrl(getString(sourcesNode[i_source], "url"));
                            // sourceSvn->setRevision(getString(sourcesNode[i_source], "revision"));
                            // sourceSvn->setUsername(getString(sourcesNode[i_source], "username"));
                            // sourceSvn->setPassword(getString(sourcesNode[i_source], "password"));
                            // sourceSvn->setTag(getString(sourcesNode[i_source], "tag"));
                            // sourceSvn->setPath(getString(sourcesNode[i_source], "path"));
                            // sourceSvn->setDepth(getString(sourcesNode[i_source], "depth"));
                            buildSources.push_back(sourceSvn);
                        }
                        else if (source_type == "patch")
                        {
                            shared_ptr<KMBuilderSourcePatch> sourcePatch = make_shared<KMBuilderSourcePatch>();
                            sourcePatch->setBaseDir(saved_demarshalBaseDir);
                            // if (getString(sourcesNode[i_source], "path") != "")
                            //     sourcePatch->addPath(getString(sourcesNode[i_source], "path"));

                            // auto paths_node = sourcesNode[i_source]["paths"];
                            // if (paths_node.IsDefined())
                            // {
                            //     for (int i_source = 0; i_source < paths_node.size(); i_source++)
                            //     {
                            //         string path_str = paths_node[i_source].as<string>();
                            //         sourcePatch->addPath(path_str);
                            //     }
                            // }
                            // if (getString(sourcesNode[i_source], "strip-components") != "")
                            //     sourcePatch->setStripComponents(atoi(getString(sourcesNode[i_source], "strip-components").c_str()));
                            // else
                            //     sourcePatch->setStripComponents(1);
                            // sourcePatch->setUsegit(getString(sourcesNode[i_source], "use-git"));
                            // sourcePatch->setOption(getString(sourcesNode[i_source], "options"));
                            // sourcePatch->setUsegitam(getString(sourcesNode[i_source], "use-git-am"));
                            buildSources.push_back(sourcePatch);
                        }
                    }
                    builderModule->setBuildSources(buildSources);
                }
            }

            builderModule->setConfigOptions(getStringArray(*iter, "config-opts"));
            builderModule->setBuildCommands(getStringArray(*iter, "build-commands"));
            builderModule->setCleanupPlatform(getStringArray(*iter, "cleanup-platform"));
            builderModule->setPostInstalls(getStringArray(*iter, "post-install"));

            // 处理 module 包含的 module
            builderModule->setBuilderModules(getNodeModules(*iter));
            builderModule->setBuildOptions(getBuildOptions(*iter));

            m_modules.push_back(builderModule);
        }
    }
    return m_modules;
}

const string KMBuilderConfigYaml::getString(const YAML::Node &node, const string &key)
{
    YAML::Node stringNode = node[key];
    if (!stringNode.IsDefined())
        return string();

    return stringNode.Type() == YAML::NodeType::Scalar ? stringNode.as<string>() : string();
}

const bool KMBuilderConfigYaml::getBool(const YAML::Node &node, const string &key)
{
    YAML::Node boolNode = node[key];
    if (!boolNode.IsDefined())
        return key == "separate-locales" || key == "appstream-compose" ? true : false;

    return boolNode.Type() == YAML::NodeType::Scalar ? boolNode.as<bool>() : (key == "separate-locales" || key == "appstream-compose" ? true : false);
}

const vector<string> KMBuilderConfigYaml::getStringArray(const YAML::Node &node, const string &key)
{
    vector<string> stringArray;

    YAML::Node stringArrayNode = node[key];
    if (!stringArrayNode.IsDefined())
        return stringArray;

    if (stringArrayNode.Type() == YAML::NodeType::Sequence)
    {
        for (YAML::Node::const_iterator iter = stringArrayNode.begin(); iter != stringArrayNode.end(); iter++)
        {
            stringArray.push_back((*iter).as<std::string>());
        }
    }

    return stringArray;
}
