//
// Created by Ht on 2022/10/1.
//

#ifndef INC_0_LIBDEVCPP_COSSDEVPROPERTYUTIL_H
#define INC_0_LIBDEVCPP_COSSDEVPROPERTYUTIL_H

#include <qlibc/qlibc.h>
#include "../DevTree/DevTree.h"

namespace jedge {

    class JE_API CossDevPropertyUtil {
    public:

        static  bool isStringInJsonArray(const Json::Value& val, const std::string& str) {
            if(!val.isArray() || val.empty()) return false;
            for(const auto& v : val) {
                if(v.isString() && strcmp(v.asCString(), str.c_str())==0)
                    return true;
            }
            return false;
        }

        static  bool removeStringFromJsonArray(Json::Value& val, const std::string& str) {
            if((!val.isArray() || val.empty())) return false;
            int i = (int)val.size()-1;
            for(;i>=0;i--) {
                const auto& v = val[i];
                if(v.isString() &&
                strcmp(v.asCString(), str.c_str())==0) {
                    Json::Value del;
                    val.removeIndex(i, &del);
                    return true;
                }
            }
            return false;
        }

        static bool addStringToJsonArray(Json::Value& group, const std::string& strVal) {
            if(!group.isArray()) {
                if (group.isString()) {
                    auto old = group.asString();
                    group = Json::arrayValue;
                    group.append(old);
                } else {
                    group = Json::arrayValue;
                }
            }
            //查重
            for(const auto& ov : group) {
                if(ov.isString() && strVal==ov.asString())
                    return false;
            }
            group.append(strVal);
            return true;
        }

        //从一个设备的字符串数组的属性中移除一个指定的值,如果为空,则删除这个属性
        static void removeStringFromJsonArrayProperty(DevTree& devTree, const std::string& devId, const std::string& propName, const std::string& strVal ) {
            Json::Value group;
            devTree.getDevInfoAsJsonValue(group, devId, propName);
            //从数组中移除一个值,如果非数组的值,直接返回false
            if(removeStringFromJsonArray(group, strVal))
            {
                if(group.empty())
                    devTree.deleteDeviceInfo(devId, propName);
                else
                    devTree.updateDeviceInfo(devId, propName, StringUtils::valueToJsonString(group));
            }
        }

        //更新设备的组地址引用增加一个不会重复的string值，如果该值不是数组，则拓展为数组
        static void addStringToJsonArrayProperty(DevTree& devTree, const std::string& devId, const std::string& propName, const std::string& strVal ) {
            Json::Value group;
            devTree.getDevInfoAsJsonValue(group, devId, propName);
            //从数组中移除一个值
            if(addStringToJsonArray(group, strVal))
            {
                if(group.empty())
                    devTree.deleteDeviceInfo(devId, propName);
                else
                    devTree.updateDeviceInfo(devId, propName, StringUtils::valueToJsonString(group));
            }
        }

        //设备的数组属性是否为空
        static bool isJsonArrayPropertyEmpty(DevTree& devTree, const std::string& devId, const std::string& propName) {
            Json::Value group;
            devTree.getDevInfoAsJsonValue(group, devId, propName);
            auto validContent = group.isInt() || (group.isArray() && !group.empty()) || (group.isString() && !group.empty());
            return !validContent;
        }

        //测试属性值是否位于某值中
        static bool isStrValExistsInJsonArrayProperty(DevTree& devTree, const std::string& devId, const std::string& propName, const std::string& strVal) {
            Json::Value group;
            devTree.getDevInfoAsJsonValue(group, devId, propName);
            auto exists = ((group.isArray() && !group.empty() && isStringInJsonArray(group, strVal))
                    || (group.isString() && strcmp(group.asCString(), strVal.c_str())==0));
            return exists;
        }
    };

}

#endif //INC_0_LIBDEVCPP_COSSDEVPROPERTYUTIL_H
