/*
 * Copyright (c) KylinSoft  Co., Ltd. 2024. All rights reserved.
 *
 * kaiming is licensed under the GPL v2.0+.
 * 
 * See the LICENSE file for more details.
 */

#include <fnmatch.h>
#include "KMParseSummaryJson.h"

#include "common/KMLogger.h"
#include "common/KMInstalledAppQuery.h"
#include "common/KMVersion.h"
#include "common/KMFormatter.h"

class KMParseSummaryJson::Private
{
public:
    Private();
    ~Private();

    json m_jsonData;
    bool m_isJsonLoaded = false;
    SummaryInfo m_summaryInfo;
    string completeRef;
    std::vector<std::string> allCompleteRefs;
    std::shared_ptr<KMFormatter> m_format;
    bool m_isThereDbusService = true;
    std::string m_notInstallable;
    vector<std::string> m_vecNotFoundAppid;
    bool m_cacheValid = false;
    std::string m_currentLocale;
    std::unordered_map<std::string, std::string> m_idArch2CompleteRef;
};

KMParseSummaryJson::Private::Private()
{
}

KMParseSummaryJson::Private::~Private()
{
}

KMParseSummaryJson::KMParseSummaryJson()
    : d(make_shared<Private>())
{
    d->m_format = shared_ptr<KMFormatter>(new KMFormatter());
}

KMParseSummaryJson::KMParseSummaryJson(const std::string &filePath)
    : d(make_shared<Private>())
{
    std::ifstream inputFile(filePath);

    if (inputFile.is_open())
    {
        std::string jsonContent((std::istreambuf_iterator<char>(inputFile)), std::istreambuf_iterator<char>());
        std::string cleanedJson = removeComments(jsonContent); // 移除注释
        std::cout << cleanedJson << std::endl;

        // 使用 nlohmann::json 解析
        d->m_jsonData = json::parse(cleanedJson);

        // d->m_jsonData = json::parse(inputFile); // 解析带注释的 json 文件会报错，需要直接赋值，否则会报错
        inputFile.close();
    }
    else
    {
        throw std::runtime_error("Unable to open json file");
    }
}

KMParseSummaryJson::~KMParseSummaryJson()
{
}

void KMParseSummaryJson::clearCache()
{
    d->m_isJsonLoaded = false;
}

std::string KMParseSummaryJson::removeComments(const std::string &jsonString)
{
    std::regex commentPattern(R"(\/\/[^\n]*|\/\*[\s\S]*?\*\/)");
    return std::regex_replace(jsonString, commentPattern, "");
}

KMErrorCodeEnum KMParseSummaryJson::loadFile(const std::string &filePath, bool forceReload)
{
    fs::path p(filePath);
    if (!fs::exists(p)) {
        clearCache();
        return KM_ERROR_LOAD_FILE_FAILED;
    }

    // 如果不强制重载，且文件已加载，则使用缓存
    if (!forceReload && d->m_isJsonLoaded)
    {
        kmlogger.info("using cached json data from %s", filePath.c_str());
        return KM_ERROR_NO;
    }

    std::ifstream inputFile(filePath);
    if (!inputFile.is_open())
    {
        clearCache();
        return KM_ERROR_LOAD_FILE_FAILED;
    }

    d->m_jsonData = json::parse(inputFile);
    d->m_cacheValid = false;
    gernerateKMPackage();
    inputFile.close();

    d->m_isJsonLoaded = true;
    kmlogger.debug("loadFile success!");
    return KM_ERROR_NO;
}

bool KMParseSummaryJson::findMatchMaxVesion(KMPMRef pmRef, string moduleKey, ModuleInfo moduleData, string &maxVersionStr)
{
    vector<string> versionVector; // 保存符合条件的版本号
    std::string version;

    if (pmRef.ref.isSpecialVersion != true && !pmRef.ref.version.empty() && pmRef.ref.version[0] != '-')
    {
        KMVersion ver = KMVersion::parse(pmRef.ref.version, false);
        version = std::to_string(ver.getMajor());
    }
    else
    {
        version = pmRef.ref.version;
    }

    for (const auto &[versionKey, versionData] : moduleData.versionInfo)
    {
        if (!pmRef.ref.version.empty() && pmRef.ref.version[0] != '-')
        {
            if (pmRef.ref.isForceInstall)
            {
                if (versionKey == pmRef.ref.version)
                {
                    versionVector.push_back(versionKey);
                    break;
                }
            }
            else
            {
                if(KMStringUtils::startsWith(versionKey, version))
                {
                    KMVersion idVer = KMVersion::parse(pmRef.ref.version, false);
                    KMVersion keyVer = KMVersion::parse(versionKey, false);
                    if (versionKey >= pmRef.ref.version)
                    {
                        versionVector.push_back(versionKey);
                    }
                }
            }
        }
        else
        {
            versionVector.push_back(versionKey);
        }
    }

    if (versionVector.size() > 0)
    {
        KMVersion maxVersion = KMVersion::parse(versionVector.at(0), false);
        maxVersionStr = versionVector.at(0);
        for (const auto &version : versionVector)
        {
            KMVersion ver = KMVersion::parse(version, false);

            if (maxVersion < ver)
            {
                maxVersion = ver;
                maxVersionStr = version;
            }
        }

        // maxVersionStr = maxVersion.str();
        return true;
    }
    else
    {
        return false;
    }
}

void KMParseSummaryJson::from_json(const json &j, VersionInfo &version)
{
    if (j.contains("installed-size"))
    {
        j.at("installed-size").get_to(version.installedSize);
    }

    if (j.contains("extensions"))
    {
        j.at("extensions").get_to(version.extensions);
    }

    if (j.contains("base"))
    {
        j.at("base").get_to(version.base);
    }

    if (j.contains("runtime"))
    {
        j.at("runtime").get_to(version.runtime);
    }
    if (j.contains("depends") && j.at("depends").is_array())
    {
        j.at("depends").get_to(version.depend);
    }
}

void KMParseSummaryJson::from_json(const json &j, ModuleInfo &module)
{
    for (auto &item : j.items())
    {
        if (KMStringUtils::startsWith(item.key(), "name"))
        {
            module.nameInfo[item.key()] = item.value();
        }
        else if (KMStringUtils::startsWith(item.key(), "description"))
        {
            module.descriptionInfo[item.key()] = item.value();
        }
        else
        {
            VersionInfo versionData;
            from_json(item.value(), versionData);
            module.versionInfo[item.key()] = versionData;
        }
    }
}

void KMParseSummaryJson::from_json(const json &j, IdInfo &id)
{
    for (auto &module : j.items())
    {
        ModuleInfo moduleData;
        from_json(module.value(), moduleData);
        id.moduleInfo[module.key()] = moduleData;
    }
}

void KMParseSummaryJson::from_json(const json &j, KindInfo &kind)
{
    for (auto &id : j.items())
    {
        IdInfo idData;
        from_json(id.value(), idData);
        kind.idInfo[id.key()] = idData;
    }
}

void KMParseSummaryJson::from_json(const json &j, ArchInfo &arch)
{
    for (auto &kind : j.items())
    {
        KindInfo kindData;
        from_json(kind.value(), kindData);
        arch.kindInfo[kind.key()] = kindData;
    }
}

void KMParseSummaryJson::from_json(const json &j, ChannelInfo &channel)
{
    for (auto &arch : j.items())
    {
        // a.archInfo[arch.key()] = arch.value().get<TypeInfo>(); // 此种方式不行
        ArchInfo archData;
        from_json(arch.value(), archData);
        channel.archInfo[arch.key()] = archData;
    }
}

void KMParseSummaryJson::from_json(const json &j, SummaryInfo &summary)
{
    for (const auto &[channelKey, channelValue] : j.items())
    {
        kmlogger.debug("arch: %s value: %s", channelKey.c_str(), channelValue.dump().c_str());

        ChannelInfo channelData;
        from_json(channelValue, channelData);
        summary.channelInfo.emplace(channelKey, std::move(channelData));
    }
}

void KMParseSummaryJson::printJson()
{
    kmlogger.debug("summary.json: %s", d->m_jsonData.dump(4).c_str());

    // 第一层遍历 Json 数据
    for (auto &item : d->m_jsonData.items())
    {
        std::string valueStr = item.value().dump();
        kmlogger.debug("item: %s value: %s", item.key().c_str(), valueStr.c_str());
    }
}

void KMParseSummaryJson::buildIdArchCache() {
    // 清空旧的缓存
    d->m_idArch2CompleteRef.clear();

    // 遍历 summaryInfo
    for (const auto &[channelName, channelData] : d->m_summaryInfo.channelInfo) {
        for (const auto &[archName, archData] : channelData.archInfo) {
            for (const auto &[kindName, kindData] : archData.kindInfo) {
                // 只处理 kindName == "app"
                if (kindName != "app") continue;
                for (const auto &[idName, idData] : kindData.idInfo) {
                    for (const auto &[moduleName, moduleData] : idData.moduleInfo) {
                        // 收集所有版本号
                        std::vector<std::string> versionVector;
                        for (const auto &[versionStr, versionInfo] : moduleData.versionInfo) {
                            versionVector.push_back(versionStr);
                        }
                        if (versionVector.empty()) continue;

                        // 找到最大版本号的原始字符串
                        std::string maxVersionStr = versionVector.front();
                        KMVersion maxVersion = KMVersion::parse(maxVersionStr, true);
                        for (const auto &version : versionVector) {
                            KMVersion ver = KMVersion::parse(version, true);
                            if (maxVersion < ver) {
                                maxVersion = ver;
                                maxVersionStr = version;
                            }
                        }

                        // 检查最大版本号是否存在
                        auto vinfoIt = moduleData.versionInfo.find(maxVersionStr);
                        if (vinfoIt == moduleData.versionInfo.end()) {
                            kmlogger.warn("maxVersion %s not found in versionInfo for id %s", maxVersionStr.c_str(), idName.c_str());
                            continue;
                        }

                        // 构造 completeRef
                        std::string completeRef = channelName + "/" + archName + "/" +
                                                  kindName + "/" + idName + "/" +
                                                  moduleName + "/" + maxVersionStr + "/" +
                                                  KMUtil::formatInstalledSize(vinfoIt->second.installedSize) + "/" +
                                                  std::to_string(vinfoIt->second.installedSize) + "/";

                        // 拼接 key
                        std::string key = idName + "|" + archName;
                        d->m_idArch2CompleteRef[key] = completeRef;
                    }
                }
            }
        }
    }
}

// void KMParseSummaryJson::buildIdArchCache() {
//     d->m_idArch2CompleteRef.clear();
//     for (const auto &[channelName, channelData] : d->m_summaryInfo.channelInfo) {
//         for (const auto &[archName, archData] : channelData.archInfo) {
//             for (const auto &[kindName, kindData] : archData.kindInfo) {
//                 if (kindName != "app") continue;

//                 for (const auto &[idName, idData] : kindData.idInfo) {
//                     for (const auto &[moduleName, moduleData] : idData.moduleInfo) {
//                         // 计算 maxVersion
//                         std::vector<std::string> versionVector;
//                         for (const auto &[versionStr, versionInfo] : moduleData.versionInfo) {
//                             versionVector.push_back(versionStr);
//                         }
//                         if (versionVector.empty()) continue;
//                         KMVersion maxVersion = KMVersion::parse(versionVector.front(), true);
//                         for (const auto &version : versionVector) {
//                             KMVersion ver = KMVersion::parse(version, true);
//                             if (maxVersion < ver) {
//                                 maxVersion = ver;
//                             }
//                         }
//                         // 检查 maxVersion 是否真的存在
//                          auto vinfoIt = moduleData.versionInfo.find(maxVersion.str());
//                         // if (vinfoIt == moduleData.versionInfo.end()) {
//                         //     kmlogger.warn("maxVersion %s not found in versionInfo for id %s", maxVersion.str().c_str(), idName.c_str());
//                         //     continue;
//                         // }

//                         std::string completeRef = channelName + "/" + archName + "/" +
//                                                   kindName + "/" + idName + "/" +
//                                                   moduleName + "/" + maxVersion.str() + "/" +
//                                                   KMUtil::formatInstalledSize(vinfoIt->second.installedSize) + "/" +
//                                                   std::to_string(vinfoIt->second.installedSize) + "/";

//                         std::string key = idName + "|" + archName;
//                         d->m_idArch2CompleteRef[key] = completeRef;
//                     }
//                 }
//             }
//         }
//     }
// }

void KMParseSummaryJson::parseSummaryJson() {
    if (d->m_cacheValid) return;

    KMUtil localeUtil;
    d->m_currentLocale = localeUtil.getCurrentLocale();

    try {
        from_json(d->m_jsonData, d->m_summaryInfo);
        //buildIdArchCache();
        d->m_cacheValid = true;
    } catch (const std::exception &e) {
        kmlogger.error("Failed to parse summary.json: %s", e.what());
        d->m_cacheValid = false;
    }
}

void KMParseSummaryJson::gernerateKMPackage()
{
    printJson();
    parseSummaryJson();
    getPackagesFromSummary();
}

void KMParseSummaryJson::getPackagesFromSummary()
{
    SummaryInfo data = d->m_summaryInfo;
    fs::path packagesPath = "/opt/kaiming/packages";
    std::set<std::string> packageIds; //去重
    // 打开文件 写入模式，自动创建文件
    std::ofstream outfile(packagesPath);
    for (const auto &[channelKey, channelData] : data.channelInfo)
    {
        kmlogger.debug("channelKey: %s", channelKey.c_str()); // main, stable
        for (const auto &[archKey, archData] : channelData.archInfo)
        {
            kmlogger.debug("archKey: %s", archKey.c_str()); // x86_64, arm64
            for (const auto &[kindKey, kindData] : archData.kindInfo)
            {
                kmlogger.debug("kindKey: %s", kindKey.c_str()); // app, runtime, base, extension
                for (const auto &[idKey, idData] : kindData.idInfo)
                {
                    kmlogger.debug("idKey: %s", idKey.c_str()); // top.openkylin.Music, top.openkylin.base, top.ukui.runtime
                    packageIds.insert(idKey.c_str());
                }
            }
        }
    }

    for (const auto &id : packageIds)
    {
        outfile << id << std::endl;
    }
    outfile.close();
}

void KMParseSummaryJson::printSummaryJson(const SummaryInfo &data)
{
    for (const auto &[channelKey, channelData] : data.channelInfo)
    {
        kmlogger.debug("channelKey: %s", channelKey.c_str()); // main, stable
        for (const auto &[archKey, archData] : channelData.archInfo)
        {
            kmlogger.debug("archKey: %s", archKey.c_str()); // x86_64, arm64
            for (const auto &[kindKey, kindData] : archData.kindInfo)
            {
                kmlogger.debug("kindKey: %s", kindKey.c_str()); // app, runtime, base, extension
                for (const auto &[idKey, idData] : kindData.idInfo)
                {
                    kmlogger.debug("idKey: %s", idKey.c_str()); // top.openkylin.Music, top.openkylin.base, top.ukui.runtime
                    for (const auto &[moduleKey, moduleData] : idData.moduleInfo)
                    {
                        kmlogger.debug("moduleKey: %s", moduleKey.c_str());
                        {
                            for (const auto &[nameKey, nameData] : moduleData.nameInfo)
                            {
                                if (KMStringUtils::startsWith(nameKey, "name"))
                                {
                                    kmlogger.debug("nameKey: %s", nameKey.c_str());
                                }
                            }

                            for (const auto &[descriptionKey, descriptionData] : moduleData.descriptionInfo)
                            {
                                if (KMStringUtils::startsWith(descriptionKey, "name"))
                                {
                                    kmlogger.debug("descriptionKey: %s", descriptionKey.c_str());
                                }
                            }
                        }

                        {
                            for (const auto &[versionKey, versionData] : moduleData.versionInfo)
                            {
                                kmlogger.debug("versionKey: %s", versionKey.c_str()); // 2.0.0.0

                                // 打印每个 version
                                kmlogger.debug("installedSize: %ld base: %s runtime: %s", versionData.installedSize, versionData.base.empty() ? "" : versionData.base.c_str(),
                                               versionData.runtime.empty() ? "" : versionData.runtime.c_str());

                                if (!versionData.extensions.empty())
                                {
                                    kmlogger.debug(" Extension: ");
                                    for (const auto &ext : versionData.extensions)
                                    {
                                        if (!ext.empty())
                                        {
                                            kmlogger.debug("ext: %s", ext.c_str());
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

string KMParseSummaryJson::toLowerUtf8(const std::string &str)
{
    wstring_convert<std::codecvt_utf8<wchar_t>> converter;
    wstring wstr = converter.from_bytes(str);
    transform(wstr.begin(), wstr.end(), wstr.begin(),
              [](wchar_t c)
              { return std::towlower(c); });
    return converter.to_bytes(wstr);
}

std::vector<std::string> KMParseSummaryJson::printSearchJson(const string &searchId, const string &specifyArch, const string &specifyKind, const string &specifyModule, bool isPrint, bool isGetDevel) {
    // std::string key = searchId + "|" + specifyArch;
    // auto it = d->m_idArch2CompleteRef.find(key);
    // if (it != d->m_idArch2CompleteRef.end())
    // {
    //     return it->second;
    // }
    d->allCompleteRefs.clear();

    // 初始化最大宽度
    size_t maxIdWidth = 0;
    size_t maxNameWidth = 0;
    size_t maxVersionWidth = 0;
    
    // 第一次遍历：计算最大宽度
    if (isPrint) {
        auto calculateMaxWidths = [&](const KMEntry& entry) {
            maxIdWidth = std::max(maxIdWidth, entry.id.length());
            maxNameWidth = std::max(maxNameWidth, entry.name.length());
            maxVersionWidth = std::max(maxVersionWidth, entry.version.length());
        };

        const string searchIdLower = toLowerUtf8(searchId);
        auto matchId = [](const string &pattern, const string &text) -> bool {
            if (pattern.find('*') != string::npos) {
                return fnmatch(pattern.c_str(), text.c_str(), FNM_NOESCAPE) == 0;
            }
            return text.find(pattern) != string::npos;
        };

        // 仅计算宽度，不打印
        for (const auto &[channelName, channelData] : d->m_summaryInfo.channelInfo) {
            for (const auto &[archName, archData] : channelData.archInfo) {
                if (!specifyArch.empty() && archName != specifyArch) continue;
                
                for (const auto &[kindName, kindData] : archData.kindInfo) {
                    if (!specifyKind.empty() && kindName != specifyKind) continue;
                    
                    for (const auto &[idName, idData] : kindData.idInfo) {
                        const string idLower = toLowerUtf8(idName);
                        if (!matchId(searchIdLower, idLower)) continue;
                        
                        for (const auto &[moduleName, moduleData] : idData.moduleInfo) {
                            if (!specifyModule.empty() && moduleName != specifyModule) continue;
                            
                            // 获取本地化名称和描述
                            const string localeNameKey = "name[" + d->m_currentLocale + "]";
                            const string localeDescKey = "description[" + d->m_currentLocale + "]";
                            
                            KMEntry tmpEntry;
                            tmpEntry.id = idName;
                            tmpEntry.name = moduleData.nameInfo.count(localeNameKey) && 
                                         !moduleData.nameInfo.at(localeNameKey).empty()
                                        ? moduleData.nameInfo.at(localeNameKey)
                                        : moduleData.nameInfo.at("name");
                            tmpEntry.version = moduleData.versionInfo.begin()->first; // 取第一个版本计算宽度
                            
                            calculateMaxWidths(tmpEntry);
                        }
                    }
                }
            }
        }

        // 设置最小宽度（确保不小于列标题）
        const size_t minIdWidth = 10;      // "ID" 标题长度
        const size_t minNameWidth = 20;    // "Name" 标题长度
        const size_t minVersionWidth = 15; // "Version" 标题长度

        maxIdWidth = std::max(maxIdWidth, minIdWidth) + 5;
        maxNameWidth = std::max(maxNameWidth, minNameWidth) + 5;
        maxVersionWidth = std::max(maxVersionWidth, minVersionWidth) + 5;

        if (isPrint) 
        {
            if (specifyModule == "devel") {
                d->m_format->setShowBase(true);
                d->m_format->setShowRuntime(true);
            }
            d->m_format->setColumnWidth(maxIdWidth, maxNameWidth, maxVersionWidth, 10, 15, 15, 30, 15, 25, 25);
            d->m_format->setShowArch(false);
            d->m_format->setShowChannel(true);
            d->m_format->printHeader();
        }
    }

    // 第二次遍历：实际处理数据并打印
    d->completeRef.clear();
    const string searchIdLower = toLowerUtf8(searchId);
    KMEntry entry;
    vector<string> versionVector;
    versionVector.reserve(10);

    auto matchId = [](const string &pattern, const string &text) -> bool {
        if (pattern.find('*') != string::npos) {
            return fnmatch(pattern.c_str(), text.c_str(), FNM_NOESCAPE) == 0;
        }
        return text.find(pattern) != string::npos;
    };

    // Iterate through cached summary info
    for (const auto &[channelName, channelData] : d->m_summaryInfo.channelInfo) {
        entry.channel = channelName;

        for (const auto &[archName, archData] : channelData.archInfo) {
            if (!specifyArch.empty() && archName != specifyArch) {
                continue;
            }
            entry.arch = archName;

            for (const auto &[kindName, kindData] : archData.kindInfo) {
                if (!specifyKind.empty() && kindName != specifyKind) {
                    continue;
                }

                for (const auto &[idName, idData] : kindData.idInfo) {
                    const string idLower = toLowerUtf8(idName);
                    if (!matchId(searchIdLower, idLower)) {
                        continue;
                    }
                    entry.id = idName;

                    for (const auto &[moduleName, moduleData] : idData.moduleInfo) {
                        if (!specifyModule.empty() && moduleName != specifyModule) {
                            continue;
                        }
                        entry.module = moduleName;

                        // Get localized name and description
                        const string localeNameKey = "name[" + d->m_currentLocale + "]";
                        const string localeDescKey = "description[" + d->m_currentLocale + "]";

                        entry.name = moduleData.nameInfo.count(localeNameKey) && 
                                    !moduleData.nameInfo.at(localeNameKey).empty()
                                   ? moduleData.nameInfo.at(localeNameKey)
                                   : moduleData.nameInfo.at("name");

                        entry.description = moduleData.descriptionInfo.count(localeDescKey) && 
                                          !moduleData.descriptionInfo.at(localeDescKey).empty()
                                         ? moduleData.descriptionInfo.at(localeDescKey)
                                         : moduleData.descriptionInfo.at("description");

                        versionVector.clear();
                        for (const auto &[versionStr, versionInfo] : moduleData.versionInfo) {
                            entry.version = versionStr;
                            if (searchId == idName && (moduleName == "binary" || isGetDevel)) {
                                versionVector.push_back(entry.version);
                            }

                            entry.size = KMUtil::formatInstalledSize(versionInfo.installedSize);
                            entry.base = versionInfo.base;
                            entry.runtime = versionInfo.runtime;
                            
                            if (searchId.empty())
                            {
                                d->completeRef = entry.channel + "/" + entry.arch + "/" + 
                                           kindName + "/" + entry.id + "/" + 
                                           entry.module + "/" + entry.version + "/" + 
                                           entry.size + "/" + 
                                           to_string(moduleData.versionInfo.at(entry.version).installedSize) + "/";
                                d->allCompleteRefs.push_back(d->completeRef);
                            }

                            if (isPrint) {
                                d->m_format->printEntry(entry);
                            }
                        }

                        if (!versionVector.empty()) {
                            KMVersion maxVersion = KMVersion::parse(versionVector.front(), false);
                            for (const auto &version : versionVector) {
                                KMVersion ver = KMVersion::parse(version, false);
                                if (maxVersion < ver) {
                                    maxVersion = ver;
                                }
                            }

                            d->completeRef = entry.channel + "/" + entry.arch + "/" + 
                                           kindName + "/" + entry.id + "/" + 
                                           entry.module + "/" + maxVersion.str() + "/" + 
                                           entry.size + "/" + 
                                           to_string(moduleData.versionInfo.at(maxVersion.str()).installedSize) + "/";
                            d->allCompleteRefs.push_back(d->completeRef);
                        }
                    }
                }
            }
        }
    }
    
    if (isPrint) {
        d->m_format->printFooter();
    }
    return d->allCompleteRefs;
}

bool KMParseSummaryJson::getSummaryInfo(KMPMRef &pmRef)
{
    string sortSearchRef;
    bool isSearched = false;

    for (const auto &[channelKey, channelData] : d->m_summaryInfo.channelInfo)
    {
        kmlogger.debug("channelKey: %s", channelKey.c_str());
        if (!pmRef.ref.channel.empty() && channelKey != pmRef.ref.channel)
        {
            continue;
        }

        for (const auto &[archKey, archData] : channelData.archInfo)
        {
            kmlogger.debug("archKey: %s", archKey.c_str());
            if (!pmRef.ref.arch.empty() && pmRef.ref.arch != archKey)
            {
                continue;
            }

            for (const auto &[kindKey, kindData] : archData.kindInfo)
            {
                kmlogger.debug("kindKey: %s", kindKey.c_str());
                if (!pmRef.ref.kind.empty() && pmRef.ref.kind != kindKey)
                {
                    continue;
                }

                for (const auto &[idKey, idData] : kindData.idInfo)
                {
                    kmlogger.debug("idKey: %s", idKey.c_str());
                    if (!pmRef.ref.id.empty() && pmRef.ref.id != idKey)
                    {
                        continue;
                    }

                    for (const auto &[moduleKey, moduleData] : idData.moduleInfo)
                    {
                        kmlogger.debug("moduleKey: %s", moduleKey.c_str());
                        if (!pmRef.ref.module.empty() && pmRef.ref.module != moduleKey)
                        {
                            continue;
                        }

                        // 获取 name 和 description 信息
                        getSummaryNameInfo(pmRef, moduleData);

                        {
                            string maxVersionStr;

                            bool getMaxVersionStrFlag = false;
                            getMaxVersionStrFlag = findMatchMaxVesion(pmRef, moduleKey, moduleData, maxVersionStr);

                            if (!getMaxVersionStrFlag)
                            {
                                return isSearched;
                            }

                            for (const auto &[versionKey, versionData] : moduleData.versionInfo)
                            {
                                kmlogger.debug("versionKey: %s", versionKey.c_str());
                                if (maxVersionStr != versionKey)
                                {
                                    continue;
                                }

                                isSearched = true;

                                pmRef.installedSize = versionData.installedSize;

                                // 打印每个module
                                kmlogger.debug("installedSize: %ld base: %s runtime: %s", versionData.installedSize, versionData.base.empty() ? "" : versionData.base.c_str(),
                                               versionData.runtime.empty() ? "" : versionData.runtime.c_str());
                            }
                        }
                    }
                }
            }
        }
    }

    return isSearched;
}

bool KMParseSummaryJson::getSummaryNameInfo(KMPMRef &pmRef, ModuleInfo moduleInfo)
{
    string locale = KMUtil::getCurrentLocale();
    string nameStr;
    string descriptionStr;

    for (const auto &[nameKey, nameData] : moduleInfo.nameInfo)
    {
        if (KMStringUtils::startsWith(nameKey, "name"))
        {
            kmlogger.debug("nameKey: %s", nameKey.c_str());
            if (nameKey == "name" || locale == "C")
            {
                nameStr = nameData;
            }
            else if (KMStringUtils::contains(nameKey, locale))
            {
                pmRef.name = nameData;
            }
        }
    }

    if (pmRef.name.empty())
    {
        pmRef.name = nameStr;
    }

    for (const auto &[descriptionKey, descriptionData] : moduleInfo.descriptionInfo)
    {
        if (KMStringUtils::startsWith(descriptionKey, "description"))
        {
            kmlogger.debug("descriptionKey: %s", descriptionKey.c_str());
            if (descriptionKey == "description" || locale == "C")
            {
                descriptionStr = descriptionData;
                KMStringUtils::removeTrailingNewline(descriptionStr);
            }
            else if (KMStringUtils::contains(descriptionKey, locale))
            {
                pmRef.description = descriptionData;
                KMStringUtils::removeTrailingNewline(pmRef.description);
            }
        }
    }

    if (pmRef.description.empty())
    {
        pmRef.description = descriptionStr;
    }

    return true;
}

bool KMParseSummaryJson::fuzzyMatchCompletedRef(KMPMRef pmRef, vector<string> &fuzzyMatchRefs)
{
    if (d->m_isThereDbusService)
    {
        const char *dbusmethod = "GetPackageInstallStatus";
        const char *idChar = pmRef.ref.id.c_str();
        const char *dbusInterface = "com.kylin.kysdk.applicationsec.antiinstall";
        int ret = getDbus(dbusInterface, dbusmethod, idChar);
        if (ret == -1)
        {
            d->m_isThereDbusService = false;
        }
        if (ret == 1)
        {
            d->m_notInstallable = pmRef.ref.id;
            return false;
        }
    }

    bool isSearched = false;
    string searchPath;

    auto matchVersions = [&](const auto &moduleKey, const auto &moduleData, const string &path)
    {
        if (pmRef.ref.module.empty())
        {
            if (moduleKey != "binary")
            {
                return false;
            }
        }
        else if (moduleKey != pmRef.ref.module)
        {
            return false;
        }
        return matchVersionData(pmRef, moduleKey, moduleData, path, fuzzyMatchRefs);
    };

    for (const auto &[channelKey, channelData] : d->m_summaryInfo.channelInfo)
    {
        if (!pmRef.ref.channel.empty() && channelKey != pmRef.ref.channel)
            continue;

        for (const auto &[archKey, archData] : channelData.archInfo)
        {
            if (!pmRef.ref.arch.empty() && pmRef.ref.arch != archKey)
                continue;

            for (const auto &[kindKey, kindData] : archData.kindInfo)
            {
                if (!pmRef.ref.kind.empty() && pmRef.ref.kind != kindKey)
                    continue;

                if (kindKey == "depend" && pmRef.ref.module.empty())
                {
                    pmRef.ref.module = "devel";
                }

                for (const auto &[idKey, idData] : kindData.idInfo)
                {
                    if (!pmRef.ref.id.empty() && pmRef.ref.id != idKey)
                        continue;

                    for (const auto &[moduleKey, moduleData] : idData.moduleInfo)
                    {
                        searchPath = channelKey + "/" + archKey + "/" + kindKey + "/" + idKey + "/" + moduleKey + "/";

                        if (matchVersions(moduleKey, moduleData, searchPath))
                        {
                            isSearched = true;
                            pmRef.ref.kind = kindKey;
                        }
                    }
                }
            }
        }
    }

    if (!isSearched)
    {
        d->m_vecNotFoundAppid.push_back(pmRef.ref.id);
    }

    return isSearched;
}

bool KMParseSummaryJson::matchVersionData(KMPMRef pmRef, string moduleKey, ModuleInfo moduleData, string searchRef, vector<string> &fuzzyMatchRefs)
{
    bool isSearched = false;
    string tmpSearchRef = searchRef;

    {
        string maxVersionStr;
        bool getMaxVersionStrFlag = false;
        getMaxVersionStrFlag = findMatchMaxVesion(pmRef, moduleKey, moduleData, maxVersionStr);

        if (!getMaxVersionStrFlag)
        {
            d->m_vecNotFoundAppid.push_back(pmRef.ref.id);
            return isSearched;
        }

        for (const auto &[versionKey, versionData] : moduleData.versionInfo)
        {
            searchRef = tmpSearchRef;
            kmlogger.debug("versionKey: %s", versionKey.c_str());
            if (maxVersionStr != versionKey)
            {
                continue;
            }
            string versionStr = searchRef.append(versionKey);

            isSearched = true;

            bool isMatch = false;
            for (const auto &version : fuzzyMatchRefs)
            {
                if (version.find(versionStr) != std::string::npos)
                {
                    isMatch = true;
                    break;
                }
            }

            if (isMatch)
            {
                continue;
            }

            fuzzyMatchRefs.push_back(versionStr);
            // base 获取队列
            if (!versionData.base.empty())
            {
                KMPMRef pmBaseRef = KMUtil::parseSummaryKMPMRef(versionData.base);
                pmBaseRef.ref.kind = BASE_TYPE_BASE;
                pmBaseRef.ref.module = pmRef.ref.module;

                if (!currentFuzzyRefIsInstalled(pmBaseRef))
                {
                    if (!fuzzyMatchCompletedRef(pmBaseRef, fuzzyMatchRefs))
                    {
                        return false;
                    }
                }
            }

            // runtime 获取队列
            if (!versionData.runtime.empty())
            {
                KMPMRef pmRuntimeRef = KMUtil::parseSummaryKMPMRef(versionData.runtime);
                pmRuntimeRef.ref.kind = BASE_TYPE_RUNTIME;
                pmRuntimeRef.ref.module = pmRef.ref.module;

                if (!currentFuzzyRefIsInstalled(pmRuntimeRef))
                {
                    if (!fuzzyMatchCompletedRef(pmRuntimeRef, fuzzyMatchRefs))
                    {
                        return false;
                    }
                }
            }

            // depend 获取队列
            if (!versionData.depend.empty())
            {
                for (std::string dependStr : versionData.depend)
                {
                    KMPMRef pmDependRef;
                    std::vector<std::string> tokens;
                    std::stringstream ss(dependStr);
                    std::string token;
                    while (std::getline(ss, token, '/'))
                    {
                        tokens.push_back(token); // 将切分后的部分添加到 tokens 向量中
                    }
                    if (dependStr.find('/') != std::string::npos)
                    {
                        pmDependRef.ref.arch = pmRef.ref.arch;
                        pmDependRef.ref.id = tokens[0];
                        pmDependRef.ref.version = tokens[1];
                        pmDependRef.ref.module = pmRef.ref.module;
                        pmDependRef.ref.channel = pmRef.ref.channel;
                        if (!currentFuzzyRefIsInstalled(pmDependRef))
                        {
                            if (!fuzzyMatchCompletedRef(pmDependRef, fuzzyMatchRefs))
                            {
                                return false;
                            }
                        }
                    }
                    else
                    {
                        pmDependRef.ref.arch = pmRef.ref.arch;
                        pmDependRef.ref.id = tokens[0];
                        pmDependRef.ref.version = "-";
                        pmDependRef.ref.module = pmRef.ref.module;
                        pmDependRef.ref.channel = pmRef.ref.channel;

                        if (!currentFuzzyRefIsInstalled(pmDependRef))
                        {
                            if (!fuzzyMatchCompletedRef(pmDependRef, fuzzyMatchRefs))
                            {
                                return false;
                            }
                        }
                    }
                }
            }

            // 打印每个module
            kmlogger.debug("installedSize: %ld base: %s runtime: %s", versionData.installedSize, versionData.base.empty() ? "" : versionData.base.c_str(),
                           versionData.runtime.empty() ? "" : versionData.runtime.c_str());

            // extension 获取队列
            if (!versionData.extensions.empty())
            {
                kmlogger.debug(" Extension: ");
                for (const auto &ext : versionData.extensions)
                {
                    if (!ext.empty())
                    {
                        kmlogger.debug("ext: %s", ext.c_str());
                        KMPMRef pmExtensionRef = KMUtil::parseSummaryKMPMRef(ext);
                        pmExtensionRef.ref.kind = BASE_TYPE_EXTENSION;

                        if (!fuzzyMatchCompletedRef(pmExtensionRef, fuzzyMatchRefs))
                        {
                            return false;
                        }
                    }
                }
            }
        }
    }

    if (isSearched == false)
    {
        d->m_vecNotFoundAppid.push_back(pmRef.ref.id);
    }

    return isSearched;
}

bool KMParseSummaryJson::currentFuzzyRefIsInstalled(KMPMRef &pmRef)
{
    KMInstalledAppQuery query;
    bool isInstalled = false;

    string kindStr = pmRef.ref.kind.empty() ? "" : pmRef.ref.kind;
    string versionStr = "";
    string channelStr = pmRef.ref.channel.empty() ? "" : pmRef.ref.channel;
    string moduleStr = pmRef.ref.module.empty() ? "binary" : pmRef.ref.module;

    std::vector<KMRef> queryVector = query.kind(kindStr).id(pmRef.ref.id).channel(channelStr).version(versionStr).module(moduleStr).query(KMInstalledAppQuery::All);

    KMVersion installedVersion;
    KMVersion currentVersion;

    if (!queryVector.empty())
    {
        if (pmRef.ref.version[0] == '-')
        {
            isInstalled = true;
            return isInstalled;
        }
        currentVersion = KMVersion::parse(pmRef.ref.version, false);

        // 指定版本，则检查是否已安装
        for (const auto &ref : queryVector)
        {
            installedVersion = KMVersion::parse(ref.version, false);
            if (ref.kind == "base" || ref.kind == "runtime" || ref.kind == "depend")
            {
                if (installedVersion.getMajor() == currentVersion.getMajor())
                {
                    if (installedVersion >= currentVersion)
                    {
                        isInstalled = true;
                        break;
                    }
                }
            }
        }
    }
    return isInstalled;
}

int KMParseSummaryJson::getDbus(const char *interfaceName, const char *methodName, const char *package)
{
    GError *error = NULL;

    // 1. 连接到系统总线
    GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
    if (!connection)
    {
        kmlogger.error("D-Bus connection failed: %s", error->message);
        g_clear_error(&error);
        return -1;
    }

    // 2. 检查服务是否存在
    GVariant *services = g_dbus_connection_call_sync(
        connection,
        "org.freedesktop.DBus",
        "/org/freedesktop/DBus",
        "org.freedesktop.DBus",
        "ListNames",
        NULL,
        G_VARIANT_TYPE("(as)"),
        G_DBUS_CALL_FLAGS_NONE,
        -1,
        NULL,
        &error);

    if (error)
    {
        kmlogger.error("Failed to list DBus services: %s", error->message);
        g_clear_error(&error);
        g_object_unref(connection);
        return -1;
    }

    // 3. 检查目标服务是否在列表中
    GVariantIter *iter;
    g_variant_get(services, "(as)", &iter);
    gboolean service_found = FALSE;
    const char *service_name;

    while (g_variant_iter_next(iter, "s", &service_name))
    {
        if (g_strcmp0(service_name, "com.kylin.kysdk.applicationsec") == 0)
        {
            service_found = TRUE;
            break;
        }
    }
    g_variant_iter_free(iter);
    g_variant_unref(services);

    if (!service_found)
    {
        kmlogger.error("DBus service 'com.kylin.kysdk.applicationsec' not found");
        g_object_unref(connection);
        return -1;
    }

    // 4. 调用目标方法
    GVariant *params = g_variant_new("(s)", package);
    GVariant *result = g_dbus_connection_call_sync(
        connection,
        "com.kylin.kysdk.applicationsec",
        "/com/kylin/kysdk/applicationsec",
        interfaceName,
        methodName,
        params,
        G_VARIANT_TYPE("(i)"),
        G_DBUS_CALL_FLAGS_NONE,
        -1,
        NULL,
        &error);

    // 5. 处理调用结果
    int ret = 1; // 默认禁止安装
    if (error)
    {
        gint32 response_value;
        kmlogger.error("D-Bus call '%s.%s' failed: %s", interfaceName, methodName, error->message);
        g_variant_get(result, "(i)", &response_value);
        ret = response_value;
        g_clear_error(&error);
    }
    else if (!result)
    {
        kmlogger.error("D-Bus call returned NULL");
    }
    else
    {
        gint32 response_value;
        g_variant_get(result, "(i)", &response_value);
        kmlogger.debug("D-Bus call returned: %d", response_value);
        ret = response_value;
        g_variant_unref(result);
    }

    g_object_unref(connection);
    return ret;
}

std::string KMParseSummaryJson::getNotInstallable()
{
    return d->m_notInstallable;
}

vector<std::string> KMParseSummaryJson::getNotFind()
{
    return d->m_vecNotFoundAppid;
}

bool KMParseSummaryJson::clearNotInstallable()
{
    d->m_vecNotFoundAppid.clear();
    d->m_notInstallable = "";
    return true;
}