/*
 * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "parse_util.h"

#include <cinttypes>
#include <dlfcn.h>
#include <fstream>
#include <unistd.h>
#include <memory>
#include <sstream>
#include <vector>
#include <algorithm>

#include "datetime_ex.h"
#include "hisysevent_adapter.h"
#include "hitrace_meter.h"
#include "sam_log.h"
#include "string_ex.h"
#include "samgr_xcollie.h"

namespace OHOS {
using std::string;

namespace {
constexpr const char* EVENT_TYPE = "eventId";
constexpr const char* EVENT_NAME = "name";
constexpr const char* EVENT_VALUE = "value";
constexpr const char* SA_TAG_SYSTEM_ABILITY = "systemability";
constexpr const char* SA_TAG_PROCESS = "process";
constexpr const char* SA_TAG_LIB_PATH = "libpath";
constexpr const char* SA_TAG_NAME = "name";
constexpr const char* SA_TAG_DEPEND = "depend";
constexpr const char* SA_TAG_DEPEND_TIMEOUT = "depend-time-out";
constexpr const char* SA_TAG_DEPEND_TIMEOUT_COMPATIBILITY = "depend_time_out";
constexpr const char* SA_TAG_RUN_ON_CREATE = "run-on-create";
constexpr const char* SA_TAG_MODULE_UPDATE = "module-update";
constexpr const char* SA_TAG_AUTO_RESTART = "auto-restart";
constexpr const char* SA_TAG_DISTRIBUTED = "distributed";
constexpr const char* SA_TAG_CACHE_COMMON_EVENT = "cache-common-event";
constexpr const char* SA_TAG_DUMP_LEVEL = "dump-level";
constexpr const char* SA_TAG_CAPABILITY = "capability";
constexpr const char* SA_TAG_PERMISSION = "permission";
constexpr const char* SA_TAG_BOOT_PHASE = "bootphase";
constexpr const char* SA_TAG_SAID = "said";
constexpr const char* SA_TAG_START_ON_DEMAND = "start-on-demand";
constexpr const char* SA_TAG_STOP_ON_DEMAND = "stop-on-demand";
constexpr const char* SA_TAG_ALLOW_UPDATE = "allow-update";
constexpr const char* SA_TAG_RECYCLE_DELAYTIME = "recycle-delaytime";
constexpr const char* SA_TAG_DEVICE_ON_LINE = "deviceonline";
constexpr const char* SA_TAG_SETTING_SWITCH = "settingswitch";
constexpr const char* SA_TAG_COMMON_EVENT = "commonevent";
constexpr const char* SA_TAG_PARAM = "param";
constexpr const char* SA_TAG_TIEMD_EVENT = "timedevent";
constexpr const char* SA_TAG_RECYCLE_STRATEGY = "recycle-strategy";
constexpr const char* SA_TAG_EXTENSION = "extension";
constexpr int32_t MAX_JSON_OBJECT_SIZE = 50 * 1024;
constexpr int32_t MAX_JSON_STRING_LENGTH = 128;
constexpr int32_t FIRST_SYS_ABILITY_ID = 0x00000000;
constexpr int32_t LAST_SYS_ABILITY_ID = 0x00ffffff;
constexpr int32_t MAX_EXTENSIONO_NUM = 100;
constexpr int32_t MAX_DLOPEN_SECONDS = 60;
constexpr const char* BOOT_START_PHASE = "BootStartPhase";
constexpr const char* CORE_START_PHASE = "CoreStartPhase";
constexpr const char* HIGH_LOAD_PRIORITY = "HighPriority";
constexpr const char* MEDIUM_LOAD_PRIORITY = "MediumPriority";

enum {
    BOOT_START = 1,
    CORE_START = 2,
    OTHER_START = 3,
};

enum {
    EQ = 1,
    GREATER_EQ = 2,
    GREATER = 3,
    LESS_EQ = 4,
    LESS = 5
};
}

ParseUtil::~ParseUtil()
{
    ClearResource();
}

void ParseUtil::CloseHandle(SaProfile& saProfile)
{
    if (saProfile.handle == nullptr) {
        return;
    }
    int32_t ret = dlclose(saProfile.handle);
    if (ret) {
        HILOGW("close handle failed with errno:%{public}d!", errno);
    }
    saProfile.handle = nullptr;
}

void ParseUtil::CloseSo()
{
    for (auto& saProfile : saProfiles_) {
        CloseHandle(saProfile);
    }
}

void ParseUtil::CloseSo(int32_t systemAbilityId)
{
    for (auto& saProfile : saProfiles_) {
        if (saProfile.saId == systemAbilityId) {
            CloseHandle(saProfile);
            break;
        }
    }
}

void ParseUtil::ClearResource()
{
    CloseSo();
    saProfiles_.clear();
}

void ParseUtil::OpenSo(uint32_t bootPhase)
{
    for (auto& saProfile : saProfiles_) {
        if (saProfile.runOnCreate && saProfile.bootPhase == bootPhase) {
            OpenSo(saProfile);
        }
    }
}

void ParseUtil::OpenSo(SaProfile& saProfile)
{
    if (saProfile.handle == nullptr) {
        string dlopenTag = ToString(saProfile.saId) + "_DLOPEN";
        HITRACE_METER_NAME(HITRACE_TAG_SAMGR, dlopenTag);
        int64_t begin = GetTickCount();
        DlHandle handle = nullptr;
        if (saProfile.runOnCreate) {
            handle = dlopen(saProfile.libPath.c_str(), RTLD_NOW);
        } else {
            SamgrXCollie samgrXCollie("safwk--openso_" + ToString(saProfile.saId), MAX_DLOPEN_SECONDS);
            handle = dlopen(saProfile.libPath.c_str(), RTLD_NOW);
        }
        int64_t duration = GetTickCount() - begin;
        ReportSaLoadDuration(saProfile.saId, SA_LOAD_OPENSO, duration);
        KHILOGI("SA:%{public}d OpenSo %{public}" PRId64 "ms",
            saProfile.saId, duration);
        if (handle == nullptr) {
            std::vector<string> libPathVec;
            string fileName = "";
            SplitStr(saProfile.libPath, "/", libPathVec);
            if (libPathVec.size() > 0) {
                fileName = libPathVec[libPathVec.size() - 1];
            }
            ReportAddSystemAbilityFailed(saProfile.saId, getpid(), getuid(), fileName);
            HILOGE("SA:%{public}d dlopen %{public}s failed with errno:%{public}s!",
                saProfile.saId, fileName.c_str(), dlerror());
            return;
        }
        saProfile.handle = handle;
    } else {
        KHILOGI("SA:%{public}d handle is not null", saProfile.saId);
    }
}

bool ParseUtil::LoadSaLib(int32_t systemAbilityId)
{
    for (auto& saProfile : saProfiles_) {
        if (saProfile.saId == systemAbilityId) {
            OpenSo(saProfile);
            return true;
        }
    }
    return false;
}

const std::list<SaProfile>& ParseUtil::GetAllSaProfiles() const
{
    return saProfiles_;
}

bool ParseUtil::GetProfile(int32_t saId, SaProfile& saProfile)
{
    auto iter = std::find_if(saProfiles_.begin(), saProfiles_.end(), [saId](auto saProfile) {
        return saProfile.saId == saId;
    });
    if (iter != saProfiles_.end()) {
        saProfile = *iter;
        return true;
    }
    return false;
}

void ParseUtil::RemoveSaProfile(int32_t saId)
{
    saProfiles_.remove_if([saId] (auto saInfo) -> bool { return saInfo.saId == saId; });
}

uint32_t ParseUtil::GetBootPriorityPara(const std::string& bootPhase)
{
    if (bootPhase == BOOT_START_PHASE) {
        return static_cast<uint32_t>(BOOT_START);
    } else if (bootPhase == CORE_START_PHASE) {
        return static_cast<uint32_t>(CORE_START);
    } else {
        return static_cast<uint32_t>(OTHER_START);
    }
}

uint32_t ParseUtil::GetOndemandPriorityPara(const std::string& loadPriority)
{
    if (loadPriority == HIGH_LOAD_PRIORITY) {
        return static_cast<uint32_t>(HIGH_PRIORITY);
    } else if (loadPriority == MEDIUM_LOAD_PRIORITY) {
        return static_cast<uint32_t>(MEDIUM_PRIORITY);
    } else {
        return static_cast<uint32_t>(LOW_PRIORITY);
    }
}

bool ParseUtil::ParseSaProfiles(const string& profilePath)
{
    HILOGD("profilePath:%{private}s", profilePath.c_str());
    string realPath = GetRealPath(profilePath);
    if (!CheckPathExist(realPath.c_str())) {
        HILOGE("bad profile path!");
        return false;
    }

    if (Endswith(realPath, ".json")) {
        return ParseJsonFile(realPath);
    } else {
        HILOGE("Invalid file format, please use json file!");
        return false;
    }
}

bool ParseUtil::Endswith(const std::string& src, const std::string& sub)
{
    return (src.length() >= sub.length() && (src.rfind(sub) == (src.length() - sub.length())));
}

std::unordered_map<std::string, std::string> ParseUtil::StringToMap(const std::string& eventStr)
{
    nlohmann::json eventJson = StringToJsonObj(eventStr);
    std::unordered_map<std::string, std::string> eventMap = JsonObjToMap(eventJson);
    return eventMap;
}

nlohmann::json ParseUtil::StringToJsonObj(const std::string& eventStr)
{
    nlohmann::json jsonObj = nlohmann::json::object();
    if (eventStr.empty()) {
        return jsonObj;
    }
    nlohmann::json eventJson = nlohmann::json::parse(eventStr, nullptr, false);
    if (eventJson.is_discarded()) {
        HILOGE("parse eventStr to json failed");
        return jsonObj;
    }
    if (!eventJson.is_object()) {
        HILOGE("eventStr converted result is not a jsonObj");
        return jsonObj;
    }
    return eventJson;
}

std::unordered_map<std::string, std::string> ParseUtil::JsonObjToMap(const nlohmann::json& eventJson)
{
    std::unordered_map<std::string, std::string> eventMap;
    if (eventJson.contains(EVENT_TYPE) && eventJson[EVENT_TYPE].is_string()) {
        eventMap[EVENT_TYPE] = eventJson[EVENT_TYPE];
    } else {
        eventMap[EVENT_TYPE] = "";
    }
    if (eventJson.contains(EVENT_NAME) && eventJson[EVENT_NAME].is_string()) {
        eventMap[EVENT_NAME] = eventJson[EVENT_NAME];
    } else {
        eventMap[EVENT_NAME] = "";
    }
    if (eventJson.contains(EVENT_VALUE) && eventJson[EVENT_VALUE].is_string()) {
        eventMap[EVENT_VALUE] = eventJson[EVENT_VALUE];
    } else {
        eventMap[EVENT_VALUE] = "";
    }
    return eventMap;
}

bool ParseUtil::ParseJsonFile(const string& realPath)
{
    nlohmann::json profileJson;
    bool result = ParseJsonObj(profileJson, realPath);
    if (!result) {
        HILOGE("json file parse error!");
        return false;
    }
    HILOGD("profileJson:%{private}s", profileJson.dump().c_str());
    string process;
    GetStringFromJson(profileJson, SA_TAG_PROCESS, process);
    if (process.empty()) {
        HILOGE("profile format error: no process tag");
        return false;
    }
    if (process.length() > MAX_JSON_STRING_LENGTH) {
        HILOGE("profile format error: process is too long");
        return false;
    }
    procName_ = Str8ToStr16(process);
    if (profileJson.find(SA_TAG_SYSTEM_ABILITY) == profileJson.end()) {
        HILOGE("system ability parse error!");
        return false;
    }
    nlohmann::json& systemAbilityJson = profileJson.at(SA_TAG_SYSTEM_ABILITY);
    HILOGD("systemAbilityJson:%{private}s", systemAbilityJson.dump().c_str());
    if (!systemAbilityJson.is_array()) {
        HILOGE("system ability is not array!");
        return false;
    }
    size_t size = systemAbilityJson.size();
    for (size_t i = 0; i < size; i++) {
        SaProfile saProfile = { procName_ };
        if (!ParseSystemAbility(saProfile, systemAbilityJson[i])) {
            continue;
        }
        saProfiles_.emplace_back(saProfile);
    }
    return !saProfiles_.empty();
}

bool ParseUtil::ParseSystemAbilityGetExtension(SaProfile& saProfile, nlohmann::json& systemAbilityJson)
{
    if ((systemAbilityJson.find(SA_TAG_EXTENSION) != systemAbilityJson.end()) &&
        (systemAbilityJson[SA_TAG_EXTENSION].is_array())) {
        for (auto& item : systemAbilityJson[SA_TAG_EXTENSION]) {
            std::string extension = item.get<std::string>();
            if (extension.length() > MAX_JSON_STRING_LENGTH) {
                HILOGE("profile format error: extension() len exceed limit");
                return false;
            }
            if (saProfile.extension.size() >= MAX_EXTENSIONO_NUM) {
                HILOGE("profile format error: extension num exceed limit");
                return false;
            }

            if (std::find(saProfile.extension.begin(), saProfile.extension.end(), extension) ==
                saProfile.extension.end()) {
                saProfile.extension.push_back(extension);
            }
        }
    }
    return true;
}

bool ParseUtil::ParseSystemAbilityGetSaBaseInfo(SaProfile& saProfile, nlohmann::json& systemAbilityJson)
{
    GetInt32FromJson(systemAbilityJson, SA_TAG_NAME, saProfile.saId);
    if (saProfile.saId == 0) {
        HILOGE("profile format error: no name tag");
        return false;
    }
    if (saProfile.saId < FIRST_SYS_ABILITY_ID || saProfile.saId > LAST_SYS_ABILITY_ID) {
        HILOGE("profile format error: saId error");
        return false;
    }
    GetStringFromJson(systemAbilityJson, SA_TAG_LIB_PATH, saProfile.libPath);
    if (saProfile.libPath.empty()) {
        HILOGE("profile format error: no libPath tag");
        return false;
    }
    if (saProfile.libPath.length() > MAX_JSON_STRING_LENGTH) {
        HILOGE("profile format error: libPath is too long");
        return false;
    }
    return true;
}

bool ParseUtil::ParseSystemAbilityGetSaExtInfo(SaProfile& saProfile, nlohmann::json& systemAbilityJson)
{
    GetBoolFromJson(systemAbilityJson, SA_TAG_RUN_ON_CREATE, saProfile.runOnCreate);
    GetBoolFromJson(systemAbilityJson, SA_TAG_MODULE_UPDATE, saProfile.moduleUpdate);
    GetBoolFromJson(systemAbilityJson, SA_TAG_AUTO_RESTART, saProfile.autoRestart);
    GetBoolFromJson(systemAbilityJson, SA_TAG_DISTRIBUTED, saProfile.distributed);
    GetBoolFromJson(systemAbilityJson, SA_TAG_CACHE_COMMON_EVENT, saProfile.cacheCommonEvent);
    GetIntArrayFromJson(systemAbilityJson, SA_TAG_DEPEND, saProfile.dependSa);
    GetInt32FromJson(systemAbilityJson, SA_TAG_DEPEND_TIMEOUT, saProfile.dependTimeout);
    if (saProfile.dependTimeout == 0) {
        GetInt32FromJson(systemAbilityJson, SA_TAG_DEPEND_TIMEOUT_COMPATIBILITY, saProfile.dependTimeout);
    }
    GetInt32FromJson(systemAbilityJson, SA_TAG_DUMP_LEVEL, saProfile.dumpLevel);
    string capability;
    GetStringFromJson(systemAbilityJson, SA_TAG_CAPABILITY, capability);
    saProfile.capability = capability.length() <= MAX_JSON_STRING_LENGTH ? Str8ToStr16(capability) : u"";
    string permission;
    GetStringFromJson(systemAbilityJson, SA_TAG_PERMISSION, permission);
    saProfile.permission = permission.length() <= MAX_JSON_STRING_LENGTH ? Str8ToStr16(permission) : u"";
    string bootPhase;
    GetStringFromJson(systemAbilityJson, SA_TAG_BOOT_PHASE, bootPhase);
    saProfile.bootPhase = GetBootPriorityPara(bootPhase);
    // parse start-on-demand tag
    ParseStartOndemandTag(systemAbilityJson, SA_TAG_START_ON_DEMAND, saProfile.startOnDemand);
    // parse stop-on-demand tag
    ParseStopOndemandTag(systemAbilityJson, SA_TAG_STOP_ON_DEMAND, saProfile.stopOnDemand);
    string recycleStrategy;
    GetStringFromJson(systemAbilityJson, SA_TAG_RECYCLE_STRATEGY, recycleStrategy);
    if (!CheckRecycleStrategy(recycleStrategy, saProfile.recycleStrategy)) {
        HILOGE("profile format error: recycleStrategy: %{public}s is not immediately or low-memory",
            recycleStrategy.c_str());
        return false;
    }
    if (!ParseSystemAbilityGetExtension(saProfile, systemAbilityJson)) {
        return false;
    }
    return true;
}

bool ParseUtil::ParseSystemAbility(SaProfile& saProfile, nlohmann::json& systemAbilityJson)
{
    HILOGD("ParseSystemAbility begin");
    if (!ParseSystemAbilityGetSaBaseInfo(saProfile, systemAbilityJson)) {
        return false;
    }
    if (!ParseSystemAbilityGetSaExtInfo(saProfile, systemAbilityJson)) {
        return false;
    }
    HILOGD("ParseSystemAbility end");
    return true;
}

bool ParseUtil::CheckRecycleStrategy(const std::string& recycleStrategyStr, int32_t& recycleStrategy)
{
    if (recycleStrategyStr == "" || recycleStrategyStr == "immediately") {
        recycleStrategy = IMMEDIATELY;
        return true;
    } else if (recycleStrategyStr == "low-memory") {
        recycleStrategy = LOW_MEMORY;
        return true;
    }
    return false;
}

bool ParseUtil::ParseJsonTag(const nlohmann::json& systemAbilityJson, const std::string& jsonTag,
    nlohmann::json& onDemandJson)
{
    if (systemAbilityJson.find(jsonTag) == systemAbilityJson.end()) {
        return false;
    }
    onDemandJson = systemAbilityJson.at(jsonTag);
    if (!onDemandJson.is_object()) {
        HILOGE("parse ondemand tag error");
        return false;
    }
    return true;
}

void ParseUtil::ParseOndemandTag(const nlohmann::json& onDemandJson, std::vector<OnDemandEvent>& onDemandEvents)
{
    GetOnDemandArrayFromJson(DEVICE_ONLINE, onDemandJson, SA_TAG_DEVICE_ON_LINE, onDemandEvents);
    GetOnDemandArrayFromJson(SETTING_SWITCH, onDemandJson, SA_TAG_SETTING_SWITCH, onDemandEvents);
    GetOnDemandArrayFromJson(COMMON_EVENT, onDemandJson, SA_TAG_COMMON_EVENT, onDemandEvents);
    GetOnDemandArrayFromJson(PARAM, onDemandJson, SA_TAG_PARAM, onDemandEvents);
    GetOnDemandArrayFromJson(TIMED_EVENT, onDemandJson, SA_TAG_TIEMD_EVENT, onDemandEvents);
}

void ParseUtil::ParseStartOndemandTag(const nlohmann::json& systemAbilityJson,
    const std::string& jsonTag, StartOnDemand& startOnDemand)
{
    nlohmann::json onDemandJson;
    if (!ParseJsonTag(systemAbilityJson, jsonTag, onDemandJson)) {
        return;
    }
    ParseOndemandTag(onDemandJson, startOnDemand.onDemandEvents);
    GetBoolFromJson(onDemandJson, SA_TAG_ALLOW_UPDATE, startOnDemand.allowUpdate);
}

void ParseUtil::ParseStopOndemandTag(const nlohmann::json& systemAbilityJson,
    const std::string& jsonTag, StopOnDemand& stopOnDemand)
{
    nlohmann::json onDemandJson;
    if (!ParseJsonTag(systemAbilityJson, jsonTag, onDemandJson)) {
        return;
    }
    ParseOndemandTag(onDemandJson, stopOnDemand.onDemandEvents);
    GetBoolFromJson(onDemandJson, SA_TAG_ALLOW_UPDATE, stopOnDemand.allowUpdate);
    GetInt32FromJson(onDemandJson, SA_TAG_RECYCLE_DELAYTIME, stopOnDemand.delayTime);
}

void ParseUtil::GetOnDemandArrayFromJson(int32_t eventId, const nlohmann::json& obj,
    const std::string& key, std::vector<OnDemandEvent>& out)
{
    if (obj.find(key.c_str()) != obj.end() && obj[key.c_str()].is_array()) {
        for (auto& item : obj[key.c_str()]) {
            std::string name;
            GetStringFromJson(item, "name", name);
            std::string value;
            GetStringFromJson(item, "value", value);
            bool persistence = false;
            GetBoolFromJson(item, "persistence", persistence);
            std::vector<OnDemandCondition> conditions;
            GetOnDemandConditionsFromJson(item, "conditions", conditions);
            HILOGD("conditions size: %{public}zu", conditions.size());
            bool enableOnce = false;
            GetBoolFromJson(item, "enable-once", enableOnce);
            std::string priority;
            GetStringFromJson(item, "load-priority", priority);
            uint32_t loadPriority = GetOndemandPriorityPara(priority);
            std::map<std::string, std::string> extraMessages;
            GetOnDemandExtraMessagesFromJson(item, "extra-messages", extraMessages);
            HILOGD("extraMessages size: %{public}zu", extraMessages.size());
            if (!name.empty() && name.length() <= MAX_JSON_STRING_LENGTH &&
                value.length() <= MAX_JSON_STRING_LENGTH) {
                OnDemandEvent event = {eventId, name, value, -1, persistence,
                    conditions, enableOnce, loadPriority, extraMessages};
                out.emplace_back(event);
            }
        }
    }
}

void ParseUtil::GetOnDemandExtraMessagesFromJson(const nlohmann::json& obj,
    const std::string& key, std::map<std::string, std::string>& out)
{
    if (obj.find(key.c_str()) == obj.end() || !obj[key.c_str()].is_object()) {
        return;
    }
    for (auto &it: obj[key.c_str()].items()) {
        if (it.value().is_string()) {
            out[it.key()] = it.value();
        } else {
            HILOGW("extra-mesasge: not string type");
        }
    }
}

void ParseUtil::GetOnDemandConditionsFromJson(const nlohmann::json& obj,
    const std::string& key, std::vector<OnDemandCondition>& out)
{
    nlohmann::json conditionsJson;
    if (obj.find(key.c_str()) == obj.end() || !obj[key.c_str()].is_array()) {
        return;
    }
    conditionsJson = obj.at(key.c_str());
    for (auto& condition : conditionsJson) {
        std::string type;
        GetStringFromJson(condition, "eventId", type);
        std::string name;
        GetStringFromJson(condition, "name", name);
        std::string value;
        GetStringFromJson(condition, "value", value);
        int32_t eventId = 0;
        if (type == SA_TAG_DEVICE_ON_LINE) {
            eventId = DEVICE_ONLINE;
        } else if (type == SA_TAG_SETTING_SWITCH) {
            eventId = SETTING_SWITCH;
        } else if (type == SA_TAG_COMMON_EVENT) {
            eventId = COMMON_EVENT;
        } else if (type == SA_TAG_PARAM) {
            eventId = PARAM;
        } else if (type == SA_TAG_TIEMD_EVENT) {
            eventId = TIMED_EVENT;
        } else {
            HILOGW("invalid condition eventId: %{public}s", type.c_str());
            continue;
        }
        std::map<std::string, std::string> extraMessages;
        GetOnDemandExtraMessagesFromJson(condition, "extra-messages", extraMessages);
        OnDemandCondition conditionEvent = {eventId, name, value, extraMessages};
        out.emplace_back(conditionEvent);
    }
}

std::u16string ParseUtil::GetProcessName() const
{
    return procName_;
}

string ParseUtil::GetRealPath(const string& profilePath) const
{
    char path[PATH_MAX] = {'\0'};
    if (realpath(profilePath.c_str(), path) == nullptr) {
        HILOGD("get real path fail");
        return "";
    }
    string realPath(path);
    return realPath;
}

bool ParseUtil::CheckPathExist(const string& profilePath)
{
    std::ifstream profileStream(profilePath.c_str());
    return profileStream.good();
}

bool ParseUtil::ParseTrustConfig(const string& profilePath,
    std::map<std::u16string, std::set<int32_t>>& values)
{
    HILOGD("config path:%{private}s", profilePath.c_str());
    string realPath = GetRealPath(profilePath);
    if (!CheckPathExist(realPath.c_str())) {
        HILOGE("bad profile path!");
        return false;
    }
    nlohmann::json trustSaIdJson;
    bool result = ParseJsonObj(trustSaIdJson, realPath);
    if (!result) {
        HILOGE("trust json file parse error!");
        return false;
    }
    string process;
    GetStringFromJson(trustSaIdJson, SA_TAG_PROCESS, process);
    if (process.empty()) {
        HILOGE("trust profile format error: no process tag");
        return false;
    }
    if (process.length() > MAX_JSON_STRING_LENGTH) {
        HILOGE("trust profile format error: process is too long");
        return false;
    }
    auto& saIds = values[Str8ToStr16(process)];
    GetIntArrayFromJson(trustSaIdJson, SA_TAG_SAID, saIds);
    HILOGI("ParseTrustConfig realPath:%{public}s, saIds size = %{public}zu", realPath.c_str(), saIds.size());
    return true;
}

bool ParseUtil::ParseJsonObj(nlohmann::json& jsonObj, const string& jsonPath)
{
    std::ifstream jsonFileStream;
    jsonFileStream.open(jsonPath.c_str(), std::ios::in);
    if (!jsonFileStream.is_open()) {
        HILOGE("open json file error!!");
        return false;
    }
    std::ostringstream buffer;
    char ch;
    int32_t readSize = 0;
    while (buffer && jsonFileStream.get(ch)) {
        readSize++;
        if (readSize < MAX_JSON_OBJECT_SIZE) {
            buffer.put(ch);
        } else {
            jsonFileStream.close();
            HILOGE("too big json file error!!");
            return false;
        }
    }
    jsonFileStream.close();
    string jsonStr = buffer.str();
    jsonObj = nlohmann::json::parse(jsonStr, nullptr, false);
    if (jsonObj.is_discarded()) {
        HILOGE("parse json obj error!!");
        return false;
    }
    return true;
}

bool ParseUtil::CheckLogicRelationship(const std::string& state, const std::string& profile)
{
    HILOGD("CheckLogicRelationship State:%{public}s || Profile:%{public}s", state.c_str(), profile.c_str());
    if (profile.empty() || state == profile) {
        return true;
    }
    if (state.empty()) {
        return false;
    }
    int32_t logicRelationship = EQ;
    int32_t valueStartPosition = 0;
    if (profile[0] == '>') {
        valueStartPosition ++;
        if (profile[1] == '=') {
            valueStartPosition ++;
            logicRelationship = GREATER_EQ;
        } else {
            logicRelationship = GREATER;
        }
    } else if (profile[0] == '<') {
        valueStartPosition ++;
        if (profile[1] == '=') {
            valueStartPosition ++;
            logicRelationship = LESS_EQ;
        } else {
            logicRelationship = LESS;
        }
    }
    int32_t stateInt, profileInt;
    if (!StrToInt(profile.substr(valueStartPosition, profile.length() - 1), profileInt)) {
        return false;
    }
    if (!StrToInt(state, stateInt)) {
        return false;
    }
    if (logicRelationship == EQ) {
        return stateInt == profileInt;
    } else if (logicRelationship == GREATER_EQ) {
        return stateInt >= profileInt;
    } else if (logicRelationship == GREATER) {
        return stateInt > profileInt;
    } else if (logicRelationship == LESS_EQ) {
        return stateInt <= profileInt;
    } else if (logicRelationship == LESS) {
        return stateInt < profileInt;
    }
    return false;
}
} // namespace OHOS