#ifndef BMSER_CJSON_H_
#define BMSER_CJSON_H_

#ifdef __cplusplus
extern "C"
{
#endif

#define MAX_JSON_STRING_SIZE 1024

typedef enum {
    JSON_VALUE_NONE,
    JSON_VALUE_STRING,
    JSON_VALUE_NUMBER
} JsonValueType;

typedef struct {
    JsonValueType type;
    long long int64Val;
    double doubleVal;
    char stringVal[MAX_JSON_STRING_SIZE];
} JsonValue;

/**
 * @brief 解析 JSON 文本并获取指定路径上 JSON 数组的长度。
 *
 * @param[in] json_text JSON 文本字符串。例:
 {
    "configFile": "DebugViewConfig",
    "frames": [
        {
            "frame_id": "",
            "regs": [
                {
                    "key": "iedname",
                    "value": "bmser"
                },
                {
                    "key": "packnum",
                    "value": 10
                }
            ]
        }
    ],
    "identifier": "systemParameterConfig",
    "mi": 1700640408784,
    "sn": "00000000"
}
 * @param[in] path 要获取数组长度的 JSON 路径。例:frames[0].regs
 * @return int 成功时返回数组的长度, 如果输入无效或者项不存在返回-1。
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2023-12-08           JHC        创建初始版本          \n
 */
int json_get_array_length(const char* json_text, const char* path);

/**
 * @brief 解析 JSON 对象并获取指定路径上 JSON 数组的长度。(适用于比较大的配置文件)
 *
 * @param[in] json parse后的JSON对象。
 * @param[in] path 要获取数组长度的 JSON 路径。例:frames[0].regs
 * @return int 成功时返回数组的长度, 如果输入无效或者项不存在返回-1。
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2023-12-08           JHC        创建初始版本          \n
 */
int json_get_array_length_by_json(void* json, const char* path);

/**
 * @brief 根据给定的 JSON 文本和路径获取数据，并填充到结果结构体中。
 *
 * @param[in] json_text JSON 文本字符串。例:
 {
    "configFile": "DebugViewConfig",
    "frames": [
        {
            "frame_id": "",
            "regs": [
                {
                    "key": "iedname",
                    "value": "bmser"
                },
                {
                    "key": "packnum",
                    "value": 10
                }
            ]
        }
    ],
    "identifier": "systemParameterConfig",
    "mi": 1700640408784,
    "sn": "00000000"
}
 * @param[in] path 路径字符串，指定要获取数据的路径。例:frames[0].regs[0].key
 * @param[out] result 指向 JsonValue 结构体的指针，用于存放获取到的数据。
 * @return int 成功时返回0, 失败时返回-1。
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2023-12-08           JHC        创建初始版本          \n
 */
int json_value_get_by_json_path(const char* json_text, const char* path, JsonValue* result);

/**
 * @brief 根据给定的json对象和路径获取数据，并填充到结果结构体中。(适用于比较大的配置文件)
 * @param[in] json cJSON parse后的json对象
 * @param[in] path 路径字符串，指定要获取数据的路径。例:frames[0].regs[0].key
 * @param[out] result 指向 JsonValue 结构体的指针，用于存放获取到的数据。
 * @return int 成功时返回0, 失败时返回-1。
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2023-12-08           JHC        创建初始版本          \n
 */
int json_value_get_by_json(void* json, const char* path, JsonValue* result);

/**
 * @brief 读取文件内容并返回文件的全部文本内容。
 * @param[i] fileName 需要读取的文件名。
 * @return 返回指向文件内容的指针。需要由调用者负责释放这段内存。若出错，则返回NULL。
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2023-12-08           JHC        创建初始版本          \n
 */
char* jsonFileContent_read(const char* fileName);

/**
 * @brief 释放由jsonFileContent_read分配的内存。
 * @param[i] fileContent 指向要释放的内存的指针
 * @return
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2024-01-05           QZY        创建初始版本          \n
 */
void free_jsonFileContent(char* fileContent);

 /**
  * @brief 读取json文件内容并返回解析后的root对象
  * @param[i] fileName 需要读取的文件名。
  * @return 返回指向root对象的void*指针。需要由调用者负责释放这段内存。若出错，则返回NULL。
  * @par         修改日志:
  * Date                Author     Description           \n
  * 2024-01-05           QZY        创建初始版本          \n
  */
void* get_jsonItem_by_fileContent(const char* fileName);

/**
 * @brief 根据消息内容并返回解析后的root对象
 * @param[i] msg 消息内容。
 * @return 返回指向root对象的void*指针。需要由调用者负责释放这段内存。若出错，则返回NULL。
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2024-02-07           JHC        创建初始版本          \n
 */
void* get_jsonItem_by_msgContent(const char* msg);

/**
 * @brief 释放JSON对象的资源
 * @param[in] json 通过JSON对象
 * @par         修改日志:
 * Date                Author     Description
 * 2024-01-05          QZY        创建初始版本
 */
void free_jsonItem(void* json);
#ifdef __cplusplus
}
#endif

#endif // !BMSER_CJSON

