
#ifndef KMUPDATE_H
#define KMUPDATE_H

#include <dbus/dbus.h>
#include <sys/stat.h> // 包含 chmod 函数的头文件

#include <cctype>     // 包含 isupper 函数
#include <cstdlib>    // 用于 std::system 函数
#include <functional> // 进度条函数
#include <initializer_list>
#include <iomanip> // For std::fixed and std::setprecision
#include <set>
#include <sstream>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "app/KMSubCommand.h"
#include "common/KMContext.h"
#include "common/KMEnv.h"
#include "common/KMFolder.h"
#include "common/KMInstance.h"
#include "common/KMOSTreeHandler.h"
#include "common/KMOption.h"
#include "common/KMOptions.h"
#include "common/KMParseDeploy.h"
#include "common/kmtranslation.h"
#include "third-party/simpleini/SimpleIni.h"

using namespace std;

typedef struct _UpdateProgressStatus
{
    string refId;
    int progress;
    string speed;
    int timeout;
} UpdateProgressStatus;

typedef function<void(std::string updateProgressStatus)> UpdateCallBack;

/**
 * @brief update command
 */
class KMUpdate : public KMSubCommand
{
    DECLARE_DYNCREATE(KMUpdate);

public:
    KMUpdate();
    virtual ~KMUpdate();

    int despose(int argc, char **argv) override;
    void init();
    int start(const vector<string> &vecName);

    bool testUpdate(string name, string version);

    /* Todo: 软件商店回调接口 */
    int update(string name, string version, int &error, UpdateCallBack updateCallback);
    int isUpgradabled(string name);

private:
    /* 组装与分拆 ref 接口*/
    // static KMCommonRef makeRefDataFromInitRefString(std::string pref);
    string makeCompletedRef(string id, string arch, string branch);
    std::string getRuntimeFromRef(KMCommonRef &ref);
    std::string getBaseTypeFromRef(KMCommonRef &ref);
    std::string getBaseTypeFromRef(string ref);
    std::string getDefaultId();
    std::string getDefaultAppVersionRef(KMCommonRef &ref);
    std::string getDefaultRuntimeVersionRef(KMCommonRef &ref);

    /* 安装校验接口 */
    bool currentRefIsInstalled(KMCommonRef &ref);
    bool currentRefStringIsInstalled(string name);
    bool isUpgradable(string name);

    /* 获取下载列表 */
    bool getDownloadRefsList(KMCommonRef &ref, char *metadata);
    void parseExtensionWithTag(const char *extension, char **name, char **tag);

    /* 部署安装脚本*/
    bool createExportBinShellScript(KMCommonRef ref, string fileName);

    /* 文件操作通用接口 */
    void createFileForEmptyString(const std::string &filename);
    void createFileIfNotExist(const std::string &filename);

    /* 解析键值对文件或数据接口 */
    std::vector<std::string> getDataFromKVFile(const std::string &filename);
    bool setDataToKVFile(const std::string &filename, const std::vector<std::string> &newLines);
    std::string getValueByKeyFromKVData(const std::vector<std::string> &lines, string key);
    std::string getValueByGroupAndKeyFromKVData(const std::string &metadata, const std::string &groupName, const std::string &key);

    /* 更改部署文件，如 .desktop, .service, 创建所有软链接等 */
    bool getAllFilesInDirectory(const std::string &directoryPath, std::vector<std::string> &files);
    void modifyServiceFile(KMCommonRef &ref, string serviceFileDirectoryPath);
    void modifyDesktopFile(KMCommonRef &ref, string exportDesktopFilePath);
    void modifyExportsDirectory(KMCommonRef &ref, const std::string &srcDir, const std::string &destDir);

    /* 更改部署文件后的缓存信息，如 desktop， mimes, icon 缓存 */
    void runMultiperTriggerUpdateCacheCommand(const vector<string> &cacheShellPaths);
    void runTriggerUpdateCacheCommand(const std::string &cacheShellPath);

    /* 用户命令行交互接口 */
    bool isInteger(const std::string &str);
    void printRefInfo(KMCommonRef &ref, int index);
    string formatFileSize(double size);

private:
    class Options;
    class Private;
    std::unique_ptr<Private> d;
};

#endif // KMUPDATE_H
