#ifndef __BUILDER_GLOBAL_H__
#define __BUILDER_GLOBAL_H__

#include <algorithm>
#include <fstream>
#include <iostream>
#include <memory>
#include <sstream>
#include <string>
#include <variant>
#include <vector>

#include <gio/gio.h>
#include <json/json.h>
#include <ostree.h>
#include <yaml-cpp/yaml.h>

#include "KMBuilderCache.h"
#include "KMBuilderConfigTypes.h"
#include "KMBuilderContext.h"
#include "KMBuilderUtils.h"
#include "common/KMLogger.h"

using namespace std;

typedef enum
{
    KAIMING_CP_FLAGS_NONE = 0,
    KAIMING_CP_FLAGS_MERGE = 1 << 0,
    KAIMING_CP_FLAGS_NO_CHOWN = 1 << 1,
    KAIMING_CP_FLAGS_MOVE = 1 << 2,
} KaimingCpFlags;

/*
类名: KMBuilderGlobal
功能: 用于获取全局唯一的配置数据
成员变量:
   - shared_ptr<ConfigData> m_pConfigData;       	        //ConfigData配置文件指针
   - KMBuilderModule *m_pBuilderModule; 			        //BuilderModule私有嵌套BuilderModuleData
   - shared_ptr<BuilderModuleData> m_pBuilderModuleData;	//BuilderModuleData指针
成员函数:
   - 省略
*/
class KMBuilderGlobal
{
public:
    KMBuilderGlobal();
    virtual ~KMBuilderGlobal();

public:
    /**
     * @brief : 获取所有的KMBuildOptions
     * @return: KMBuildOptions列表
     */
    vector<shared_ptr<KMBuildOptions>> getAllBuildOptions();
    /**
     * @brief : 根据builderOptions来获取AppendedPath
     * @return: AppendedPath
     */
    string builderOptionsGetAppendedPath(string pathList, int type);
    /**
     * @brief : 根据builderOptions来获取BuildArgs
     * @return: BuildArgs列表
     */
    vector<string> builderOptionsGetBuildArgs();
    /**
     * @brief : 根据builderOptions来获取Env
     * @return: Env列表
     */
    vector<string> builderOptionsGetEnv();
    /**
     * @brief : 更新环境变量Env
     */
    void builderOptionsUpdatePath(int type, vector<string> &envs);
    /**
     * @brief : 设置环境变量SOURCE_DATE_EPOCH
     */
    void setEnvSDE(vector<string> &envs);
    /**
     * @brief : 设置环境变量CCACHE_DIR和PATH，并存储环境变量到Env
     */
    void builderContextExtendEnvPost(vector<string> &envs);
    /**
     * @brief : 搜集需要cleanup的文件路径
     */
    void builderModuleCleanupCollect(shared_ptr<KMBuilderModule> builderModule, bool platform, std::unordered_map<std::string, bool> &to_remove_ht);
    /**
     * @brief : 检测path是否符合需要cleanup的patterns模式匹配
     */
    bool matchesCleanupForPath(vector<string> patterns, string path);
    /**
     * @brief : 检测path是否符合需要cleanup的patterns模式匹配,并将符合的路径存储到哈希表中
     */
    void kaimingCollectMatchesForPathPattern(string path, string pattern, string addPrefix, std::unordered_map<std::string, bool> &to_remove_ht);
    /**
     * @brief : 轮询patterns，调用kaimingCollectMatchesForPathPattern
     */
    void collectCleanupForPath(vector<string> patterns, string path, string addPrefix, std::unordered_map<std::string, bool> &to_remove_ht);

    /**
     * @brief : 获取ref
     */
    string kaimingComposeRef(bool app, string name, string branch, string arch);
    /**
     * @brief : 返回app开头的ref路径
     */
    string kaimingBuildAppRef(string app, string branch, string arch);
    /**
     * @brief : 返回runtime开头的ref路径
     */
    string kaimingBuildRuntimeRef(string runtime, string branch, string arch);

    /**
     * @brief : 递归拷贝文件
     */
    bool cpAll(string src, string dest, string keepInToplevel, KaimingCpFlags flags, vector<string> skipFiles);
    /**
     * @brief : 确认toplevel是否被包含于file
     */
    bool fileIsIn(string file, string toplevel);
    /**
     * @brief :确认文件存在且获取规范唯一路径
     */
    string canonicalizeFile(string path);
    /**
     * @brief :复制同样的UID到目标文件
     */
    bool cpUID(string srcPath, string descPath);
    /**
     * @brief :复制同样的mod权限到目标文件
     */
    bool cpMod(string srcPath, string descPath);
    /**
     * @brief : 从buildOptions中获取多种flags
     * @param type : 1-4 分别对应 cflags，cppflags，cxxflags，ldflags
     * @return:
     */
    string buildOptionsGetFlags(int type);

    /**
     * @brief : 规范化id之后加后缀
     * @param suffix : 需要添加的后缀
     * @return : 组合之后的字符串
     */
    string configGetVariousId(string suffix);

    /**
     * @brief : 获取清单内的app-id/id配置
     * @return: app-id
     */
    std::string appId();

    /**
     * @brief : 规范化id-platform之后加后缀
     * @param suffix : 需要添加的后缀
     * @return : 组合之后的字符串
     */
    string configGetVariousIdPlatform(string suffix);

    /**
     * @brief : 查询branch
     * @return :
     */
    string configGetBranch();

private:
    shared_ptr<ConfigData> m_pConfigData;               // ConfigData配置文件指针
    KMBuilderModule *m_pBuilderModule;                  // BuilderModule私有嵌套BuilderModuleData
    shared_ptr<BuilderModuleData> m_pBuilderModuleData; // BuilderModuleData指针
};

#endif /* __BUILDER_GLOBAL_H__ */
