/*
 * Copyright (C) 2024 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.
 */

#ifndef SERVICES_INCLUDE_SYS_CFG_PARSE_H
#define SERVICES_INCLUDE_SYS_CFG_PARSE_H

#include "input_method_status.h"
#include "input_method_utils.h"
#include "serializable.h"
namespace OHOS {
namespace MiscServices {
struct SaInfo : public Serializable {
    std::string name;
    int32_t id{ -1 };
    bool Unmarshal(cJSON *node) override
    {
        auto ret = GetValue(node, GET_NAME(name), name);
        ret = GetValue(node, GET_NAME(id), id) && ret;
        return ret;
    }
};

struct SystemConfig : public Serializable {
    static constexpr const char *IME_DAU_STATISTICS_CAP_NAME = "ime_dau_statistics";
    static constexpr const char *HA_SERVICE_NAME = "haService";
    std::string systemInputMethodConfigAbility;
    std::string defaultInputMethod;
    bool enableInputMethodFeature = false;
    bool enableFullExperienceFeature = false;
    EnabledStatus initEnabledState{ EnabledStatus::DISABLED };
    bool enableAppAgentFeature = false;
    bool enableNumKeyFeature = false;
    std::unordered_set<std::string> disableNumKeyAppDeviceTypes;
    std::unordered_set<int32_t> proxyImeUidList;
    std::unordered_set<int32_t> specialSaUidList;
    std::unordered_set<std::string> defaultImeScreenList;
    std::unordered_set<std::string> defaultMainDisplayScreenList;
    std::unordered_set<std::string> supportedCapacityList;
    std::vector<SaInfo> dependentSaList;
    std::string systemPanelAppIdentifier;
    bool disableImmersiveMode = false;

    bool Unmarshal(cJSON *node) override
    {
        GetValue(node, GET_NAME(systemInputMethodConfigAbility), systemInputMethodConfigAbility);
        GetValue(node, GET_NAME(defaultInputMethod), defaultInputMethod);
        GetValue(node, GET_NAME(enableInputMethodFeature), enableInputMethodFeature);
        GetValue(node, GET_NAME(enableFullExperienceFeature), enableFullExperienceFeature);
        auto enableState = static_cast<int32_t>(EnabledStatus::DISABLED);
        GetValue(node, GET_NAME(initEnabledState), enableState);
        initEnabledState = static_cast<EnabledStatus>(enableState);
        GetValue(node, GET_NAME(enableAppAgentFeature), enableAppAgentFeature);
        GetValue(node, GET_NAME(enableNumKeyFeature), enableNumKeyFeature);
        GetValue(node, GET_NAME(disableNumKeyAppDeviceTypes), disableNumKeyAppDeviceTypes);
        GetValue(node, GET_NAME(proxyImeUidList), proxyImeUidList);
        GetValue(node, GET_NAME(specialSaUidList), specialSaUidList);
        GetValue(node, GET_NAME(defaultImeScreenList), defaultImeScreenList);
        GetValue(node, GET_NAME(defaultMainDisplayScreenList), defaultMainDisplayScreenList);
        GetValue(node, GET_NAME(supportedCapacityList), supportedCapacityList);
        GetValue(node, GET_NAME(dependentSaList), dependentSaList);
        GetValue(node, GET_NAME(systemPanelAppIdentifier), systemPanelAppIdentifier);
        GetValue(node, GET_NAME(disableImmersiveMode), disableImmersiveMode);
        return true;
    }
};
struct ImeSystemConfig : public Serializable {
    SystemConfig systemConfig;
    bool Unmarshal(cJSON *node) override
    {
        return GetValue(node, GET_NAME(systemConfig), systemConfig);
    }
};

struct InputTypeInfo : public Serializable {
    InputType type{ InputType::NONE };
    std::string bundleName;
    std::string subName;
    bool Unmarshal(cJSON *node) override
    {
        int32_t typeTemp = -1;
        auto ret = GetValue(node, GET_NAME(inputType), typeTemp);
        if (typeTemp <= static_cast<int32_t>(InputType::NONE) || typeTemp >= static_cast<int32_t>(InputType::END)) {
            return false;
        }
        type = static_cast<InputType>(typeTemp);
        ret = GetValue(node, GET_NAME(bundleName), bundleName) && ret;
        ret = GetValue(node, GET_NAME(subtypeId), subName) && ret;
        return ret;
    }
};
struct InputTypeCfg : public Serializable {
    std::vector<InputTypeInfo> inputType;
    bool Unmarshal(cJSON *node) override
    {
        return GetValue(node, GET_NAME(supportedInputTypeList), inputType);
    }
};

struct DynamicStartImeCfgItem : public Serializable {
    std::string sysParam;
    std::string value;
    DynamicStartImeCfgItem(const std::string &sysParam = "", const std::string &value = "")
    {
        this->sysParam = sysParam;
        this->value = value;
    }

    bool Unmarshal(cJSON *node) override
    {
        auto ret = GetValue(node, GET_NAME(sysParam), sysParam);
        ret = GetValue(node, GET_NAME(value), value) && ret;
        return ret;
    }
};

struct DynamicStartImeCfg : public Serializable {
    std::vector<DynamicStartImeCfgItem> dynamicStartImeCfgList;
    bool Unmarshal(cJSON *node) override
    {
        return GetValue(node, GET_NAME(dynamicStartImeCfgList), dynamicStartImeCfgList);
    }
};

struct SysPanelAdjust : public Serializable {
    std::vector<std::string> style;
    int32_t top = 0;
    int32_t left = 0;
    int32_t right = 0;
    int32_t bottom = 0;
    bool Unmarshal(cJSON *node) override
    {
        auto ret = GetValue(node, GET_NAME(style), style);
        ret = GetValue(node, GET_NAME(top), top) && ret;
        ret = GetValue(node, GET_NAME(left), left) && ret;
        ret = GetValue(node, GET_NAME(right), right) && ret;
        ret = GetValue(node, GET_NAME(bottom), bottom) && ret;
        return ret;
    }
};

struct SysPanelAdjustCfg : public Serializable {
    std::vector<SysPanelAdjust> panelAdjust;
    bool Unmarshal(cJSON *node) override
    {
        return GetValue(node, GET_NAME(sysPanelAdjust), panelAdjust);
    }
};

struct DefaultFullImeInfo : public Serializable {
    std::string appId;
    std::string expirationTime;
    uint32_t expirationVersionCode{ 0 };
    bool Unmarshal(cJSON *node) override
    {
        bool ret = GetValue(node, GET_NAME(appIdentifier), appId);
        ret &= GetValue(node, GET_NAME(expirationTime), expirationTime);
        GetValue(node, GET_NAME(expirationVersionCode), expirationVersionCode);
        return ret;
    }
};

struct DefaultFullImeCfg : Serializable {
    std::vector<DefaultFullImeInfo> defaultFullImeList;
    bool Unmarshal(cJSON *node) override
    {
        return GetValue(node, GET_NAME(defaultFullImeList), defaultFullImeList);
    }
};

struct IgnoreSysPanelAdjust : public Serializable {
    std::vector<int32_t> inputType;
    bool Unmarshal(cJSON *node) override
    {
        return GetValue(node, GET_NAME(inputType), inputType);
    }
};

struct IgnoreSysPanelAdjustCfg : public Serializable {
    IgnoreSysPanelAdjust ignoreSysPanelAdjust;
    bool Unmarshal(cJSON *node) override
    {
        return GetValue(node, GET_NAME(ignoreSysPanelAdjust), ignoreSysPanelAdjust);
    }
};

struct ProductConfig : public Serializable {
    bool disabledMemoryWatermark = false;
    bool isSupportPcMode = false;
    bool disablePcModeImmersiveMode = false;
    bool Unmarshal(cJSON *node) override
    {
        GetValue(node, GET_NAME(disabledMemoryWatermark), disabledMemoryWatermark);
        GetValue(node, GET_NAME(isSupportPcMode), isSupportPcMode);
        GetValue(node, GET_NAME(disablePcModeImmersiveMode), disablePcModeImmersiveMode);
        return true;
    }
};

struct ImeProductConfig : public Serializable {
    ProductConfig productConfig;
    bool Unmarshal(cJSON *node) override
    {
        return GetValue(node, GET_NAME(productConfig), productConfig);
    }
};

class SysCfgParser {
public:
    static bool ParseSystemConfig(SystemConfig &systemConfig);
    static bool ParseProductConfig(ProductConfig &productConfig);
    static bool ParseInputType(std::vector<InputTypeInfo> &inputType);
    static bool ParsePanelAdjust(std::vector<SysPanelAdjust> &sysPanelAdjust);
    static bool ParseDefaultFullIme(std::vector<DefaultFullImeInfo> &defaultFullImeList);
    static bool ParseIgnoreSysPanelAdjust(IgnoreSysPanelAdjust &ignoreSysPanelAdjust);
    static bool ParseDynamicStartImeCfg(std::vector<DynamicStartImeCfgItem> &dynamicStartImeCfgList);
    static bool IsContainField(const std::string& fieldName);
private:
    static std::string GetSysCfgContent(const std::string &key);
};
} // namespace MiscServices
} // namespace OHOS
#endif // SERVICES_INCLUDE_SYS_CFG_PARSE_H