#include "event_query.h"
#include "event_process.h"
#include "bmser_log.h"
#include "bmser_ipc.h"
#include "bmser_cjson.h"
#include "bmser_dev.h"
#include "dtc_export_cfg_parse.h"
#include "cJSON.h"
#include "sqlite_api.h"
#include "communication.h"
#include "dtc_db3_common.h"
#include "bmser_project_para.h"
#include "toolkit.h"

#include <sqlite3.h>
#include <string.h>

#define MAX_DEV_NUM   64
#define MAX_BANK_NUM  32
#define MAX_SQL_LENGTH (1024*MAX_BANK_NUM)
#define MAX_SUB_SQL_LENGTH (1024*(MAX_BANK_NUM-1))
#define SUB_SQL_LENGTH (1024)

struct bank_filter
{
	int bank_id;
	int location_dev_num; //筛选的设备个数
	int location_num[MAX_DEV_NUM];//指定筛选的设备ID，0表示堆，非0表示堆下簇ID
};

struct call_back_data
{
	int rows;
	struct event_table_info* events;
};

// revert,1,3;  revert是操作名,1为写入值,3为地址
struct operate_parse{
    char key[50];  // 存储 revert
    int value;     // 存储 1
    int addr;    // 存储 3
};

struct ui_level_remap
{
    int actual_level;
    int ui_level;
};

struct ui_level_remap g_levelRemap[ ] = 
{
    {  .actual_level=3,     .ui_level=3  },
    {  .actual_level=2,     .ui_level=2  },
    {  .actual_level=1,     .ui_level=1  },
    {  .actual_level=0,     .ui_level=1  },
}; 
#define LEVEL_REMAP_NUM            SIZE_OF_ARRAY(g_levelRemap)

struct ui_level_remap g_dtc_levelRemap[] = 
{
    {  .actual_level=11,    .ui_level=11  },  // 事件级别11: UI不展示
    {  .actual_level=10,    .ui_level=10  },  // 事件级别10: 展示"事件"
    {  .actual_level=3,     .ui_level=1  },
    {  .actual_level=2,     .ui_level=2  },
    {  .actual_level=1,     .ui_level=3  },
    {  .actual_level=0,     .ui_level=1  },
}; 
#define DTC_LEVEL_REMAP_NUM            SIZE_OF_ARRAY(g_dtc_levelRemap)
#define MAX_LEVEL_NUM                  MAX(LEVEL_REMAP_NUM, DTC_LEVEL_REMAP_NUM)

struct alarm_filter
{
	int page;
	int page_size;
	long long mi;
	char sn[SN_MAX_LEN];
	char dev_sn[SN_MAX_LEN];
	int level_num;
	int level[MAX_LEVEL_NUM];
    int continer_filter_num;
    int continer_filter_array[MAX_BANK_NUM*2];
	int bank_filter_num;
    int64_t start_time; //unix
    int64_t end_time;   //unix
	struct bank_filter lot_bank[MAX_BANK_NUM];
};

static int dtc_get_actual_level(int ui_level)
{
    int i = 0;

    for (i = 0; i < DTC_LEVEL_REMAP_NUM; i++)
    {
        if (ui_level == g_dtc_levelRemap[i].ui_level) {
            return g_dtc_levelRemap[i].actual_level;
        }
    }
    return 0;
}

static int dtc_get_ui_level(int actual_level)
{
    int i = 0;
    for (i = 0; i < DTC_LEVEL_REMAP_NUM; i++)
    {
        if (actual_level == g_dtc_levelRemap[i].actual_level) {
            return g_dtc_levelRemap[i].ui_level;
        }
    }
    return 0;
}

static int level_conversion(int actual_level)
{
    int i = 0;

    for (i = 0; i < LEVEL_REMAP_NUM; i++)
    {
        if(actual_level == g_levelRemap[i].actual_level){
            return g_levelRemap[i].ui_level;
        }
    }
    return 0;
}

static int operate_string_parse(const char* input,struct operate_parse **results)
{
    int count = 0;  // 用于记录解析出来的组数
    const char* start = input;  // 当前解析起点
    char* end;  // 用于查找分隔符位置

    // 首先统计有多少组数据，简单起见，可以通过统计;的数量来实现
    while (*start) {
        if (*start == ';') count++;
        start++;
    }

    if (count == 0) return 0;  // 如果没有数据则直接返回

    // 根据组数分配足够的内存来存储解析结果
    *results = (struct operate_parse *)malloc(sizeof(struct operate_parse) * count);
    if (*results == NULL) return 0;  // 内存分配失败

    start = input;  // 重置起点为字符串开始
    int index = 0;  // 当前处理的是第几组数据

    while (index < count) {
        end = strchr(start, ',');  // 查找等号
        if (end == NULL) break;  // 格式错误
        strncpy((*results)[index].key, start, end - start);
        (*results)[index].key[end - start] = '\0';  // 添加字符串终止符

        start = end + 1;  // 移动到等号后的字符
        (*results)[index].value = atoi(start);  // 解析出数字

        start = strchr(start, ',');  // 查找逗号
        if (start == NULL) break;  // 格式错误
        start++;  // 移动到逗号后的字符
        (*results)[index].addr = atoi(start);  // 解析出数字

        start = strchr(start, ';');  // 查找分号，准备解析下一组数据
        if (start == NULL) break;  // 格式错误
        start++;  // 移动到分号后的字符

        index++;  // 处理下一组数据
    }

    return count;  // 返回解析出的组数
}

static int rows_callback(void *data, int argc, char **argv, char **azColName){
    int *count = (int*)data;
    *count = atoi(argv[0]);
    return 0;
}

static int result_call_back(void *data, int argc, char **argv, char **azColName)
{
    if (data == NULL || argv[0] == NULL) 
    {
        return -1;  // 返回一个非零值表示错误
    }
    struct call_back_data *cb_data = (struct call_back_data*) data;
	cb_data->events = realloc(cb_data->events, (cb_data->rows + 1) * sizeof(struct event_table_info));
	if(cb_data->events == NULL)
	{
		dy_syslog(LOG_ERR, "Insufficient memory application space\n");
		return -1;
	}

    //解析查询结果，将结果保存到结构体中去
    if (argv[1]) strncpy(cb_data->events[cb_data->rows].sn, argv[1], SN_MAX_LEN-1);
    if (argv[2]) strncpy(cb_data->events[cb_data->rows].station_guid, argv[2], NAME_MAX_LEN-1);
    if (argv[3]) cb_data->events[cb_data->rows].cabin_id = atoi(argv[3]);
    if (argv[4]) strncpy(cb_data->events[cb_data->rows].system_type, argv[4], NAME_MAX_LEN-1);
    if (argv[5]) strncpy(cb_data->events[cb_data->rows].device_type, argv[5], NAME_MAX_LEN-1);
    if (argv[6]) strncpy(cb_data->events[cb_data->rows].device_name, argv[6], NAME_MAX_LEN-1);
    if (argv[7]) cb_data->events[cb_data->rows].main_id = atoi(argv[7]);
    if (argv[8]) cb_data->events[cb_data->rows].sub_id = atoi(argv[8]);
    if (argv[9]) cb_data->events[cb_data->rows].event_id = atoi(argv[9]);
    if (argv[10]) strncpy(cb_data->events[cb_data->rows].event_name, argv[10], NAME_MAX_LEN-1);
    if (argv[11]) strncpy(cb_data->events[cb_data->rows].event_name_en, argv[11], NAME_MAX_LEN-1);
    if (argv[12]) strncpy(cb_data->events[cb_data->rows].details, argv[12], DETAIL_MAX_LEN-1);
    if (argv[13]) strncpy(cb_data->events[cb_data->rows].details_en, argv[13], DETAIL_MAX_LEN-1);
    if (argv[14]) cb_data->events[cb_data->rows].status = atoi(argv[14]);
    if (argv[15]) cb_data->events[cb_data->rows].level = atoi(argv[15]);
    if (argv[16]) cb_data->events[cb_data->rows].settime = strtol(argv[16], NULL, 10);
    if (argv[17]) cb_data->events[cb_data->rows].clrtime = strtol(argv[17], NULL, 10);
    if (argv[18]) strncpy(cb_data->events[cb_data->rows].created_at, argv[18], NAME_MAX_LEN-1);
    if (argv[19]) strncpy(cb_data->events[cb_data->rows].comfirmed_at, argv[19], NAME_MAX_LEN-1);
    if (argv[20]) strncpy(cb_data->events[cb_data->rows].operate, argv[20], DETAIL_MAX_LEN-1);
    if (argv[21]) strncpy(cb_data->events[cb_data->rows].fun, argv[21], NAME_MAX_LEN-1);
    if (argv[22]) cb_data->events[cb_data->rows].error_no = atoi(argv[22]);
    if (argv[23]) strncpy(cb_data->events[cb_data->rows].handler_user, argv[23], NAME_MAX_LEN-1);
    if (argv[24]) strncpy(cb_data->events[cb_data->rows].handler, argv[24], NAME_MAX_LEN-1);
    if (argv[25]) cb_data->events[cb_data->rows].handler_time = atoi(argv[25]);
    if (argv[26]) strncpy(cb_data->events[cb_data->rows].updated_at, argv[26], NAME_MAX_LEN-1);

    // 确保字符串以null字符结束
    cb_data->events[cb_data->rows].sn[SN_MAX_LEN-1] = '\0';
    cb_data->events[cb_data->rows].station_guid[NAME_MAX_LEN-1] = '\0';
    cb_data->events[cb_data->rows].system_type[NAME_MAX_LEN-1] = '\0';
    cb_data->events[cb_data->rows].device_type[NAME_MAX_LEN-1] = '\0';
    cb_data->events[cb_data->rows].device_name[NAME_MAX_LEN-1] = '\0';
    cb_data->events[cb_data->rows].event_name[NAME_MAX_LEN-1] = '\0';
    cb_data->events[cb_data->rows].event_name_en[NAME_MAX_LEN-1] = '\0';
    cb_data->events[cb_data->rows].details[DETAIL_MAX_LEN-1] = '\0';
    cb_data->events[cb_data->rows].details_en[DETAIL_MAX_LEN-1] = '\0';
    cb_data->events[cb_data->rows].created_at[NAME_MAX_LEN-1] = '\0';
    cb_data->events[cb_data->rows].comfirmed_at[NAME_MAX_LEN-1] = '\0';
    cb_data->events[cb_data->rows].operate[DETAIL_MAX_LEN-1] = '\0';
    cb_data->events[cb_data->rows].fun[NAME_MAX_LEN-1] = '\0';
    cb_data->events[cb_data->rows].handler_user[NAME_MAX_LEN-1] = '\0';
    cb_data->events[cb_data->rows].handler[NAME_MAX_LEN-1] = '\0';
    cb_data->events[cb_data->rows].updated_at[NAME_MAX_LEN-1] = '\0';

    cb_data->rows++;


    return 0;
}

static int clean_alarm()
{
	int rc = 0;
    rc = sqlite3_exec(g_eventdb, "delete from alarm;", NULL, NULL, NULL);
    if (rc != SQLITE_OK) {
        dy_syslog(LOG_ERR, "delete from alarm:%s\n",sqlite3_errmsg(g_eventdb));
        return -1;
    }
	rc = sqlite3_exec(g_eventdb, "vacuum;", NULL, NULL, NULL);
    if (rc != SQLITE_OK) {
        dy_syslog(LOG_ERR, "vacuum error:%s\n",sqlite3_errmsg(g_eventdb));
        return -1;
    }

	return 0;
}

void build_select_immediate_alarm_sql(struct alarm_filter *info, char* sql, int sqlLen) 
{
	if(sql == NULL){
		return;
	}
	char sub_sql_condition[MAX_SUB_SQL_LENGTH] = {0};
    char level_condition[SUB_SQL_LENGTH] = {0};
    char continer_condition[SUB_SQL_LENGTH] = {0};
    // 开始构建SQL语句

	snprintf(sql, sqlLen, 
        "SELECT * FROM alarm "
        // 左连接条件的效果是筛选出那些在左连接之后没有匹配到更高级别报警记录的原始报警记录
        "LEFT JOIN alarm AS a ON a.main_id == alarm.main_id AND a.sub_id = alarm.sub_id AND a.event_desc = alarm.event_desc AND a.level > alarm.level AND a.clrtime == 0 "
        "WHERE alarm.clrtime == 0 AND a.main_id IS NULL ");
    // 动态添加筛选条件
    for(int i = 0; i < info->bank_filter_num; i++)
    {
        char temp_1[30];
        if(i == 0){
            strcat(sub_sql_condition,"AND ( ");
        }
        snprintf(temp_1, sizeof(temp_1), "( alarm.main_id = %d ", info->lot_bank[i].bank_id);
        strcat(sub_sql_condition, temp_1);
        
        for(int j = 0; j < info->lot_bank[i].location_dev_num; j++) 
        {
            if(j == 0){
                strcat(sub_sql_condition, "AND alarm.sub_id in ( ");
            }
            char temp_2[30];
            snprintf(temp_2, sizeof(temp_2), "%d", info->lot_bank[i].location_num[j]);
            strcat(sub_sql_condition, temp_2);
            if(j < info->lot_bank[i].location_dev_num - 1){
                strcat(sub_sql_condition, ", ");
            }
            else{
                strcat(sub_sql_condition, ")");
            }
        }
        strcat(sub_sql_condition, ")");
        //如果有多个bank筛选，加入OR
        if(i < (info->bank_filter_num - 1)){
            strcat(sub_sql_condition, " OR ");
        }else if(i == (info->bank_filter_num - 1)){
            strcat(sql, sub_sql_condition);
            strcat(sql, ") ");
        }
    }

    //拼接level筛选语句
    for(int i = 0; i < info->level_num; i++){
        char temp[30];
		if(i == 0){
			strcat(sql, "AND (");
		}
        snprintf(temp, sizeof(temp), "alarm.level = %d", info->level[i]);
        strcat(level_condition, temp);

        // 如果不是最后一个level，那么加上" OR "
        if(i < info->level_num - 1) {
            strcat(level_condition, " OR ");
        }
		if(i == (info->level_num - 1)){
			// 将level条件添加到总的SQL语句中
			strcat(sql, level_condition);
			strcat(sql, ") ");
		}
    }

    //拼接continer筛选语句
    for(int i = 0; i < info->continer_filter_num; i++){
        char temp[30];
		if(i == 0){
			strcat(sql, "AND (");
		}
        snprintf(temp, sizeof(temp), "alarm.cabin_id = %d", info->continer_filter_array[i]);
        strcat(continer_condition, temp);

        // 如果不是最后一个level，那么加上" OR "
        if(i < info->continer_filter_num - 1) {
            strcat(continer_condition, " OR ");
        }
		if(i == (info->continer_filter_num - 1)){
			// 将level条件添加到总的SQL语句中
			strcat(sql, continer_condition);
			strcat(sql, ")");
		}
    }
    //  这个语句会按照指定的字段（bank ID、rackid ID、event desc和 level）对结果集进行分组，
    //  这意味着具有相同bank ID、rackid ID、event desc和 level的记录会被归入同一个组。
    strcat(sql, " GROUP BY alarm.main_id, alarm.sub_id, alarm.event_desc, alarm.level ");
    //  查询结果根据 settime 字段降序排列，这意味着最新设置的警报会首先显示。
    strcat(sql, " ORDER BY alarm.settime DESC ");
    strcat(sql, " LIMIT 0, 200 ");
    
}

void build_select_history_alarm_sql(struct alarm_filter *info, char* sql, int sqlLen) 
{
	if(sql == NULL){
		return;
	}
	char sub_sql_condition[MAX_SUB_SQL_LENGTH] = {0};
    char level_condition[SUB_SQL_LENGTH] = {0};
    char continer_condition[SUB_SQL_LENGTH] = {0};
    // 开始构建SQL语句

	snprintf(sql, sqlLen, 
        "SELECT * FROM alarm "
        "WHERE id IN ( SELECT id FROM alarm WHERE alarm.clrtime > 0 ");
    // 动态添加筛选条件
    for(int i = 0; i < info->bank_filter_num; i++){
        char temp_1[30];
        //先拼接主ID筛选条件
        if(i == 0){
            strcat(sub_sql_condition,"AND (");
        }
        snprintf(temp_1, sizeof(temp_1), "( alarm.main_id = %d ", info->lot_bank[i].bank_id);
        strcat(sub_sql_condition, temp_1);
        for(int j = 0; j < info->lot_bank[i].location_dev_num; j++){
            if(j == 0){
                //起始SQL语句拼接
                strcat(sub_sql_condition, "AND alarm.sub_id in (");
            }
            char temp_2[30];
            snprintf(temp_2, sizeof(temp_2), "%d", info->lot_bank[i].location_num[j]);
            strcat(sub_sql_condition, temp_2);
            if(j < info->lot_bank[i].location_dev_num - 1){
                strcat(sub_sql_condition, ", ");
            }
            else{
                strcat(sub_sql_condition, ")");
            }
        }
        strcat(sub_sql_condition, ")");
        if(i < (info->bank_filter_num - 1)){
            strcat(sub_sql_condition, " OR ");
        }else if(i == (info->bank_filter_num - 1)){
            strcat(sql, sub_sql_condition);
            strcat(sql, ") ");
        }
    }
    for(int i = 0; i < info->level_num; i++){
        char temp[30];
		if(i == 0){
			strcat(sql, "AND alarm.level in (");
		}
        snprintf(temp, sizeof(temp), "%d", info->level[i]);
        strcat(level_condition, temp);

        // 如果不是最后一个level，那么加上" OR "
        if(i < info->level_num - 1) {
            strcat(level_condition, ", ");
        }
		if(i == (info->level_num - 1)){
			// 将level条件添加到总的SQL语句中
			strcat(sql, level_condition);
			strcat(sql, ") ");
		}
    }

    //拼接continer筛选语句
    for(int i = 0; i < info->continer_filter_num; i++){
        char temp[30];
		if(i == 0){
			strcat(sql, "AND alarm.cabin_id in (");
		}
        snprintf(temp, sizeof(temp), "%d", info->continer_filter_array[i]);
        strcat(continer_condition, temp);

        // 如果不是最后一个level，那么加上" OR "
        if(i < info->continer_filter_num - 1) {
            strcat(continer_condition, ", ");
        }
		if(i == (info->continer_filter_num - 1)){
			// 将level条件添加到总的SQL语句中
			strcat(sql, continer_condition);
			strcat(sql, ")");
		}
    }
    if(info->start_time > 0 && info->end_time > 0)
    {
        char temp_time_select[256];
        snprintf(temp_time_select, sizeof(temp_time_select), \
            "AND (alarm.settime BETWEEN %ld AND %ld) ", \
            info->start_time,info->end_time);
        strcat(sql, temp_time_select);
    }
    strcat(sql, " ORDER BY alarm.clrtime DESC ");
    char temp_3[30];
    snprintf(temp_3, sizeof(temp_3), "LIMIT %d , %d ", (info->page-1)*info->page_size,info->page_size);
    strcat(sql, temp_3);
    strcat(sql, ") ");
    strcat(sql, " ORDER BY alarm.clrtime DESC ");
}

static void build_select_history_dtc_sql(struct alarm_filter *info, char* sql, int sqlLen) 
{
	if (sql == NULL){
		return;
	}
	char sub_sql_condition[MAX_SUB_SQL_LENGTH] = {0};
    char level_condition[SUB_SQL_LENGTH] = {0};
    char continer_condition[SUB_SQL_LENGTH] = {0};
    
    // 开始构建SQL语句
	snprintf(sql, sqlLen, "SELECT bankid,rackid,alarm_level,unixtime,dtcname,dtcname_en,issueDetails_zh_CN,issueDetails_en_US,eventName_zh_CN,eventName_en_US FROM dtc_record ");
    
    // 动态添加筛选条件
    for(int i = 0; i < info->bank_filter_num; i++){
        char temp_1[30];
        //先拼接主ID筛选条件
        if(i == 0){
            strcat(sub_sql_condition,"WHERE id IN ( SELECT id FROM dtc_record where (");
        }
        snprintf(temp_1, sizeof(temp_1), "(bankID = %d ", info->lot_bank[i].bank_id);
        strcat(sub_sql_condition, temp_1);
        for(int j = 0; j < info->lot_bank[i].location_dev_num; j++){
            if(j == 0){
                //起始SQL语句拼接
                strcat(sub_sql_condition, "AND rackID in (");
            }
            char temp_2[30] = {0};
            snprintf(temp_2, sizeof(temp_2), "%d", info->lot_bank[i].location_num[j]);
            strcat(sub_sql_condition, temp_2);
            if (j < info->lot_bank[i].location_dev_num - 1) {
                strcat(sub_sql_condition, ", ");
            }
            else {
                strcat(sub_sql_condition, ")");
            }
        }
        strcat(sub_sql_condition, ")");
        if(i < (info->bank_filter_num - 1)){
            strcat(sub_sql_condition, " OR ");
        }else if(i == (info->bank_filter_num - 1)){
            strcat(sql, sub_sql_condition);
            strcat(sql, ") ");
        }
    }

    for(int i = 0; i < info->level_num; i++){
        char temp[30] = {0};
		if(i == 0){
			strcat(sql, "AND alarm_level in (");
		}
        snprintf(temp, sizeof(temp), " %d", dtc_get_actual_level(info->level[i]));
        strcat(level_condition, temp);

        // 如果不是最后一个level，则追加", "
        if(i < info->level_num - 1) {
            strcat(level_condition, ", ");
        }
		if(i == (info->level_num - 1)){
			// 将level条件添加到总的SQL语句中
			strcat(sql, level_condition);
			strcat(sql, ") ");
		}
    }

    if(info->start_time > 0 && info->end_time > 0)
    {
        char temp_time_select[256] = {0};
        snprintf(temp_time_select, sizeof(temp_time_select), \
            "AND (unixTime BETWEEN %ld AND %ld) ", \
            info->start_time, info->end_time);
        strcat(sql, temp_time_select);
    }
    else
    {
        // 屏蔽错误响应特殊条目(时间戳为0xFFFFFFFF)
        strcat(sql, " AND (unixTime != 4294967295) ");
    }
    strcat(sql, " AND (dtcName != '') ");
    strcat(sql, " ORDER BY unixTime DESC, DBIndexID DESC ");
    char temp_3[30] = {0};
    snprintf(temp_3, sizeof(temp_3), "LIMIT %d , %d ", (info->page-1)*info->page_size,info->page_size);
    strcat(sql, temp_3);

    strcat(sql, ") ");
    strcat(sql, " ORDER BY unixTime DESC, DBIndexID DESC ");
    return;
}

static void build_select_history_dtc_count_sql(struct alarm_filter *info, char* sql, int sqlLen) 
{
	if (sql == NULL){
		return;
	}
	char sub_sql_condition[MAX_SUB_SQL_LENGTH] = {0};
    char level_condition[SUB_SQL_LENGTH] = {0};
    char continer_condition[SUB_SQL_LENGTH] = {0};
    
    // 开始构建SQL语句
	snprintf(sql, sqlLen, "SELECT count(*) FROM dtc_record ");
    
    // 动态添加筛选条件
    for(int i = 0; i < info->bank_filter_num; i++){
        char temp_1[30];
        //先拼接主ID筛选条件
        if(i == 0){
            strcat(sub_sql_condition,"WHERE ( ");
        }
        snprintf(temp_1, sizeof(temp_1), "( bankID = %d ", info->lot_bank[i].bank_id);
        strcat(sub_sql_condition, temp_1);
        for(int j = 0; j < info->lot_bank[i].location_dev_num; j++){
            if(j == 0){
                //起始SQL语句拼接
                strcat(sub_sql_condition, "AND rackID in ( ");
            }
            char temp_2[30] = {0};
            snprintf(temp_2, sizeof(temp_2), "%d", info->lot_bank[i].location_num[j]);
            strcat(sub_sql_condition, temp_2);
            if (j < info->lot_bank[i].location_dev_num - 1) {
                strcat(sub_sql_condition, ", ");
            }
            else {
                strcat(sub_sql_condition, ")");
            }
        }
        strcat(sub_sql_condition, ")");
        if(i < (info->bank_filter_num - 1)){
            strcat(sub_sql_condition, " OR ");
        }else if(i == (info->bank_filter_num - 1)){
            strcat(sql, sub_sql_condition);
            strcat(sql, ") ");
        }
    }

    for(int i = 0; i < info->level_num; i++){
        char temp[30] = {0};
		if(i == 0){
			strcat(sql, "AND (");
		}
        snprintf(temp, sizeof(temp), "alarm_level = %d", dtc_get_actual_level(info->level[i]));
        strcat(level_condition, temp);

        // 如果不是最后一个level，那么加上" OR "
        if(i < info->level_num - 1) {
            strcat(level_condition, " OR ");
        }
		if(i == (info->level_num - 1)){
			// 将level条件添加到总的SQL语句中
			strcat(sql, level_condition);
			strcat(sql, ") ");
		}
    }

    if(info->start_time > 0 && info->end_time > 0)
    {
        char temp_time_select[256] = {0};
        snprintf(temp_time_select, sizeof(temp_time_select), \
            "AND (unixTime BETWEEN %ld AND %ld) ", \
            info->start_time, info->end_time);
        strcat(sql, temp_time_select);
    }
    else
    {
        // 屏蔽错误响应记录特殊条目(时间戳为0xFFFFFFFF)
        strcat(sql, " AND (unixTime != 4294967295) ");
    }
    strcat(sql, " AND (dtcName != '') ");
    return;
}

void build_select_history_alarm_counts_sql(struct alarm_filter *info, char* sql, int sqlLen) 
{
	if(sql == NULL){
		return;
	}
	char sub_sql_condition[MAX_SUB_SQL_LENGTH] = {0};
    char level_condition[SUB_SQL_LENGTH] = {0};
    char continer_condition[SUB_SQL_LENGTH] = {0};
    // 开始构建SQL语句

	snprintf(sql, sqlLen, 
        "SELECT count(*) FROM alarm "
        "WHERE alarm.clrtime > 0 ");
    // 动态添加筛选条件
    for(int i = 0; i < info->bank_filter_num; i++){
        char temp_1[30];
        //先拼接主ID筛选条件
        if(i == 0){
            strcat(sub_sql_condition,"AND ( ");
        }
        snprintf(temp_1, sizeof(temp_1), "( alarm.main_id = %d ", info->lot_bank[i].bank_id);
        strcat(sub_sql_condition, temp_1);
        for(int j = 0; j < info->lot_bank[i].location_dev_num; j++){
            if(j == 0){
                //起始SQL语句拼接
                strcat(sub_sql_condition, "AND alarm.sub_id in ( ");
            }
            char temp_2[30];
            snprintf(temp_2, sizeof(temp_2), "%d", info->lot_bank[i].location_num[j]);
            strcat(sub_sql_condition, temp_2);
            if(j < info->lot_bank[i].location_dev_num - 1){
                strcat(sub_sql_condition, ", ");
            }
            else{
                strcat(sub_sql_condition, ")");
            }
        }
        strcat(sub_sql_condition, ")");
        if(i < (info->bank_filter_num - 1)){
            strcat(sub_sql_condition, " OR ");
        }else if(i == (info->bank_filter_num - 1)){
            strcat(sql, sub_sql_condition);
            strcat(sql, ") ");
        }
    }
    for(int i = 0; i < info->level_num; i++){
        char temp[30];
		if(i == 0){
			strcat(sql, "AND alarm.level in (");
		}
        snprintf(temp, sizeof(temp), "%d", info->level[i]);
        strcat(level_condition, temp);

        // 如果不是最后一个level，那么加上" OR "
        if(i < info->level_num - 1) {
            strcat(level_condition, ", ");
        }
		if(i == (info->level_num - 1)){
			// 将level条件添加到总的SQL语句中
			strcat(sql, level_condition);
			strcat(sql, ") ");
		}
    }

    //拼接continer筛选语句
    for(int i = 0; i < info->continer_filter_num; i++){
        char temp[30];
		if(i == 0){
			strcat(sql, "AND alarm.cabin_id in (");
		}
        snprintf(temp, sizeof(temp), "%d", info->continer_filter_array[i]);
        strcat(continer_condition, temp);

        // 如果不是最后一个level，那么加上" OR "
        if(i < info->continer_filter_num - 1) {
            strcat(continer_condition, ", ");
        }
		if(i == (info->continer_filter_num - 1)){
			// 将level条件添加到总的SQL语句中
			strcat(sql, continer_condition);
			strcat(sql, ")");
		}
    }
    if(info->start_time > 0 && info->end_time > 0)
    {
        char temp_time_select[256];
        snprintf(temp_time_select, sizeof(temp_time_select), \
            "AND (alarm.settime BETWEEN %ld AND %ld) ", \
            info->start_time,info->end_time);
        strcat(sql, temp_time_select);
    }
}

char* create_immediate_alarm_json(struct call_back_data *result, struct alarm_filter *info)
{
	if(result == NULL || info == NULL){
		return NULL;
	}

    cJSON *root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "identifier", "ImmediateAlarm");
    cJSON_AddNumberToObject(root, "time", (double)time(NULL));

    cJSON *tags = cJSON_CreateObject();
    cJSON *alarmlist = cJSON_CreateArray();
    if(tags == NULL || alarmlist == NULL){
        goto err;
    }
    if(result != NULL){
        for (int i = 0; i < result->rows; i++) {
            cJSON *alarm = cJSON_CreateObject();
            if (alarm == NULL) {
                goto err;
            }
            int level = level_conversion(result->events[i].level);
            cJSON_AddNumberToObject(alarm, "bankid", result->events[i].main_id);
            cJSON_AddNumberToObject(alarm, "rackid", result->events[i].sub_id);
            cJSON_AddNumberToObject(alarm, "level", level);
            cJSON_AddNumberToObject(alarm, "settime", result->events[i].settime);
            cJSON_AddNumberToObject(alarm, "containerId", result->events[i].cabin_id);
            if(g_language == 0){
                cJSON_AddStringToObject(alarm, "alarmitem", result->events[i].event_name);
                cJSON_AddStringToObject(alarm, "extra", result->events[i].details);
            }
            else{
                cJSON_AddStringToObject(alarm, "alarmitem", result->events[i].event_name_en);
                cJSON_AddStringToObject(alarm, "extra", result->events[i].details_en);
            }
            //当前只适配中英文
            cJSON *translations = cJSON_CreateArray();
            if (translations == NULL) {
                cJSON_Delete(alarm);
                goto err;
            }
            cJSON *string1 = cJSON_CreateString(result->events[i].event_name);
            cJSON *string2 = cJSON_CreateString(result->events[i].event_name_en);
            cJSON_AddItemToArray(translations,string1);
            cJSON_AddItemToArray(translations,string2);
            //cJSON_AddStringToObject(alarm, "sn", xxx);

            cJSON *operateArray = cJSON_CreateArray();
            if (operateArray == NULL) {
                cJSON_Delete(alarm);
                goto err;
            }
            struct operate_parse *operate_results = NULL;
            int operate_num = operate_string_parse(result->events[i].operate, &operate_results);
            for (int j = 0; j < operate_num; j++) {
                cJSON *operate = cJSON_CreateObject();
                cJSON_AddStringToObject(operate, "key", operate_results[j].key);
                cJSON_AddNumberToObject(operate, "value", operate_results[j].value);
                cJSON_AddNumberToObject(operate, "addr", operate_results[j].addr);
                cJSON_AddItemToArray(operateArray, operate);
            }
            free(operate_results);
            cJSON_AddItemToObject(alarm, "operate", operateArray);
            cJSON_AddItemToObject(alarm, "translations",translations);
            cJSON_AddItemToArray(alarmlist, alarm);
            
        }
        //sn理论上都一样，默认选一个进行读取
        cJSON_AddStringToObject(root, "sn", result->events[0].sn);
    }
    cJSON_AddItemToObject(tags, "alarmlist", alarmlist);
    cJSON_AddItemToObject(root, "tags", tags);

    cJSON_AddNumberToObject(root, "mi", info->mi);


    char *jsonString = cJSON_PrintUnformatted(root);
    cJSON_Delete(root);
    return jsonString;// 调用者负责释放这个字符串的内存
err:
    cJSON_Delete(root);
    if (tags) {
        cJSON_Delete(tags);  // 如果 tags 创建成功但 alarmlist 创建失败，删除 tags
    }
    if (alarmlist) {
        cJSON_Delete(alarmlist);  // 如果 alarmlist 创建成功但 tags 创建失败，删除 alarmlist
    }
    return NULL; 
}

char* create_history_alarm_json(struct call_back_data *result, struct alarm_filter *info)
{
	if(info == NULL)
	{
		return NULL;
	}
    int rc = 0, counts = 0, pages = 0;
    char sql[MAX_SQL_LENGTH] = {0};

    if (info->bank_filter_num == 0 || info->level_num == 0) {
        // 用户等级/堆位置 任一全不选，跳过查询记录条数，counts为0
    } else {
        build_select_history_alarm_counts_sql(info, sql, MAX_SQL_LENGTH);
        //printf("counts sql:%s\r\n",sql);
        //获取历史告警总条数
        rc = sqlite3_exec(g_eventdb, sql, rows_callback, &counts, NULL);
        if (rc != SQLITE_OK) {
            dy_syslog(LOG_ERR, "history alarm counts query error:%s\n",sqlite3_errmsg(g_eventdb));
            return NULL;
        }
        counts = counts > 10000 ? 10000 : counts;
    }

    cJSON *root = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "identifier", "HistoryAlarm");
    cJSON_AddNumberToObject(root, "time", (double)time(NULL));

    cJSON *tags = cJSON_CreateObject();
    cJSON *alarmlist = cJSON_CreateArray();
    if(result != NULL ){
        pages = (counts / info->page_size)+1;
        for (int i = 0; i < result->rows; i++) {
            cJSON *alarm = cJSON_CreateObject();
            int level = level_conversion(result->events[i].level);
            cJSON_AddNumberToObject(alarm, "bankid", result->events[i].main_id);
            cJSON_AddNumberToObject(alarm, "rackid", result->events[i].sub_id);
            cJSON_AddNumberToObject(alarm, "level", level);
            cJSON_AddNumberToObject(alarm, "settime", result->events[i].settime);
            cJSON_AddNumberToObject(alarm, "clrtime", result->events[i].clrtime);
            cJSON_AddNumberToObject(alarm, "containerId", result->events[i].cabin_id);
            if(g_language == 0)
            {
                cJSON_AddStringToObject(alarm, "alarmitem", result->events[i].event_name);
                cJSON_AddStringToObject(alarm, "extra", result->events[i].details);
            }
            else
            {
                cJSON_AddStringToObject(alarm, "alarmitem", result->events[i].event_name_en);
                cJSON_AddStringToObject(alarm, "extra", result->events[i].details_en);
            }
            //当前只适配中英文
            cJSON *translations = cJSON_CreateArray();
            if (translations == NULL) {
                cJSON_Delete(alarm);
                goto err;
            }
            cJSON *string1 = cJSON_CreateString(result->events[i].event_name);
            cJSON *string2 = cJSON_CreateString(result->events[i].event_name_en);
            cJSON_AddItemToArray(translations,string1);
            cJSON_AddItemToArray(translations,string2);
            //cJSON_AddStringToObject(alarm, "sn", xxx);
            cJSON_AddItemToObject(alarm, "translations",translations);
            cJSON_AddItemToArray(alarmlist, alarm);
        }
        //sn理论上都一样，默认选一个进行读取
        cJSON_AddStringToObject(root, "sn", result->events[0].sn);
    }
    cJSON_AddItemToObject(tags, "alarmlist", alarmlist);
    cJSON_AddNumberToObject(tags, "total", counts);
    cJSON_AddNumberToObject(tags, "pages", pages);
    cJSON_AddNumberToObject(tags, "size", info->page_size);
    cJSON_AddItemToObject(root, "tags", tags);
    cJSON_AddNumberToObject(root, "mi", info->mi);


    char *jsonString = cJSON_PrintUnformatted(root);
    cJSON_Delete(root);

    return jsonString; // 调用者负责释放这个字符串的内存
err:
    cJSON_Delete(root);
    if (tags) {
        cJSON_Delete(tags);  // 如果 tags 创建成功但 alarmlist 创建失败，删除 tags
    }
    if (alarmlist) {
        cJSON_Delete(alarmlist);  // 如果 alarmlist 创建成功但 tags 创建失败，删除 alarmlist
    }
    return NULL; 
}

static char* create_history_dtc_json(dtc_call_back_data *result, struct alarm_filter *info)
{
	if (result == NULL || info == NULL) {
		return NULL;
	}
    
    int rc = 0, pages = 0, containerId = 0;
    uint16_t counts = 0;
    char sn[SN_MAX_LEN + 1] = {0};
    cJSON *root = cJSON_CreateObject();
    char sql[MAX_SQL_LENGTH] = {0};
    
    if (root == NULL) {
        return NULL;
    }

    if (info->bank_filter_num == 0 || info->level_num == 0) {
        // 用户等级/堆位置 任一全不选，跳过查询记录条数，counts为0
    } else {
        build_select_history_dtc_count_sql(info, sql, MAX_SQL_LENGTH);
        //printf("dtc count sql: %s\n", sql);
        rc = DTC_Export_DB3_get_sql_counts(&counts, sql);
        if (0 != rc) {
            cJSON_Delete(root);
            return NULL;
        }
        counts = (counts > 10000 ? 10000 : counts);
    }
    
    cJSON_AddStringToObject(root, "identifier", "DtcHistory");
    cJSON_AddNumberToObject(root, "time", (double)time(NULL));

    cJSON *tags = cJSON_CreateObject();
    cJSON *alarmlist = cJSON_CreateArray();
    
    if (tags == NULL || alarmlist == NULL) {
        cJSON_Delete(root);
        return NULL;
    }

    bmser_dev_get_board_sn_ex(sn, SN_MAX_LEN + 1);
    containerId = bmser_jsonGetContainerNum();
    pages = (counts / info->page_size) + 1;

    for (int i = 0; i < result->rows; i++) {
        cJSON *alarm = cJSON_CreateObject();
        cJSON_AddNumberToObject(alarm, "bankid", result->events[i].bankID);
        cJSON_AddNumberToObject(alarm, "rackid", result->events[i].rackID);
        cJSON_AddNumberToObject(alarm, "level", dtc_get_ui_level(result->events[i].alarm_level));
        cJSON_AddNumberToObject(alarm, "settime", result->events[i].unixTime);
        cJSON_AddNumberToObject(alarm, "containerId", containerId);
        if(g_language == 0)
        {
            cJSON_AddStringToObject(alarm, "alarmitem", result->events[i].dtcName);
            cJSON_AddStringToObject(alarm, "extra", result->events[i].issueDetails_zh_CN);
        }
        else
        {
            cJSON_AddStringToObject(alarm, "alarmitem", result->events[i].dtcName_en);
            cJSON_AddStringToObject(alarm, "extra", result->events[i].issueDetails_en_US);
        }
        
        //当前只适配中英文
        cJSON *translations = cJSON_CreateArray();
        if (translations == NULL) {
            cJSON_Delete(alarm);
            goto err;
        }

        cJSON *string1 = cJSON_CreateString(result->events[i].eventName_zh_CN);
        cJSON *string2 = cJSON_CreateString(result->events[i].eventName_en_US);
        cJSON_AddItemToArray(translations,string1);
        cJSON_AddItemToArray(translations,string2);
        cJSON_AddItemToObject(alarm, "translations",translations);
        cJSON_AddItemToArray(alarmlist, alarm);
    }
    //sn理论上都一样，默认选一个进行读取
    cJSON_AddStringToObject(root, "sn", sn);
    cJSON_AddNumberToObject(tags, "total", counts);
    cJSON_AddItemToObject(tags, "alarmlist", alarmlist);
    cJSON_AddNumberToObject(tags, "pages", pages);
    cJSON_AddNumberToObject(tags, "size", info->page_size);
    cJSON_AddItemToObject(root, "tags", tags);
    cJSON_AddNumberToObject(root, "mi", info->mi);


    char *jsonString = cJSON_PrintUnformatted(root);
    cJSON_Delete(root);

    return jsonString; // 调用者负责释放这个字符串的内存
err:
    cJSON_Delete(root);
    if (tags) {
        cJSON_Delete(tags);  // 如果 tags 创建成功但 alarmlist 创建失败，删除 tags
    }
    if (alarmlist) {
        cJSON_Delete(alarmlist);  // 如果 alarmlist 创建成功但 tags 创建失败，删除 alarmlist
    }

    return NULL; 
}

static int immediate_alarm_query(struct alarm_filter *info)
{
	char sql[MAX_SQL_LENGTH];
	int rc;
	struct call_back_data result = {0,NULL}; // 初始化结构体指针
	char * respJson = NULL;

	if(info == NULL )
	{
		return -1;
	}

    if (info->bank_filter_num == 0 || info->level_num == 0) {
        // 用户等级/堆位置 任一全不选，跳过条目查询，上报空数据
    } else {
        build_select_immediate_alarm_sql(info, sql, MAX_SQL_LENGTH);
        //printf("immediate sql:%s\n",sql);
        rc = sqlite3_exec(g_eventdb, sql, result_call_back, &result, NULL);
        if (rc != SQLITE_OK) {
            dy_syslog(LOG_ERR, "immediate alarm query error:%s\n",sqlite3_errmsg(g_eventdb));
            goto err;
        }
    }

	//if(result.events != NULL)
	{
		struct ipc_topic t = {0};
		struct ipc_payload p = {0};
		char name[NAME_MAX_LEN] = {0};

		snprintf(name,NAME_MAX_LEN,"ipc/%s/bms/%s/data/GetResp/ImmediateAlarm",info->sn,info->dev_sn);
		t.name = name;
		respJson = create_immediate_alarm_json(&result,info);
        if(!respJson){
            goto err;
        }
		p.buf = respJson;
		p.len = strlen(respJson);
		communication_publish(&t,&p);
		free(result.events);
		free(respJson);
	}
    return 0;
err:
    if(result.events){ 
        free(result.events); 
    }
    if(respJson){
        free(respJson);
    }
    return -1;
}

static int history_alarm_query(struct alarm_filter *info)
{
	char sql[MAX_SQL_LENGTH];
	int rc;
	struct call_back_data result = {0,NULL}; // 初始化结构体指针
	char * respJson = NULL;

	if(info == NULL ){
		return -1;
	}

    if (info->bank_filter_num == 0 || info->level_num == 0) {
        // 用户等级/堆位置 任一全不选，跳过条目查询，上报空数据
    } else {
        build_select_history_alarm_sql(info, sql, MAX_SQL_LENGTH);
        //printf("history sql:%s\n",sql);
        rc = sqlite3_exec(g_eventdb, sql, result_call_back, &result, NULL);
        if (rc != SQLITE_OK) {
            dy_syslog(LOG_ERR, "history alarm query error:%s\n",sqlite3_errmsg(g_eventdb));
            goto err;
        }
    }

	//if(result.events != NULL)
    {
		struct ipc_topic t = {0};
		struct ipc_payload p = {0};
		char name[NAME_MAX_LEN] = {0};

		snprintf(name,NAME_MAX_LEN,"ipc/%s/bms/%s/data/GetResp/HistoryAlarm",info->sn,info->dev_sn);
		t.name = name;
		respJson = create_history_alarm_json(&result,info);
        if(!respJson){
            goto err;
        }
        p.buf = respJson;
        p.len = strlen(respJson);
        communication_publish(&t,&p);
        free(result.events);
        free(respJson);
        
	}
    return 0;
err:
    if(result.events){ 
        free(result.events); 
    }
    if(respJson){
        free(respJson);
    }
    return -1;
}

static int history_dtc_query(struct alarm_filter *info)
{
	char sql[MAX_SQL_LENGTH];
	int rc = 0;
    dtc_call_back_data result = {0, NULL}; // 初始化结构体指针
	char * respJson = NULL;

	if (info == NULL ){
		return -1;
	}

    if (info->bank_filter_num == 0 || info->level_num == 0) {
        // 用户等级/堆位置 任一全不选，跳过查询记录
    } else {
        build_select_history_dtc_sql(info, sql, MAX_SQL_LENGTH);
        //printf("sql:%s.\n", sql);
        rc = DTC_Export_DB3_query(sql, MAX_SQL_LENGTH, &result);
        if (rc != SQLITE_OK) {
            goto err;
        }
    }

    struct ipc_topic t = {0};
    struct ipc_payload p = {0};
    char name[NAME_MAX_LEN] = {0};

    snprintf(name,NAME_MAX_LEN,"ipc/%s/bms/%s/data/GetResp/DtcHistory",info->sn,info->dev_sn);
    t.name = name;
    respJson = create_history_dtc_json(&result,info);
    if(!respJson){
        dy_syslog(LOG_ERR, "create_history_dtc_json fail.");
        goto err;
    }
    p.buf = respJson;
    p.len = strlen(respJson);
    communication_publish(&t,&p);
    free(result.events);
    free(respJson);
        
    return 0;
err:
    if(result.events){ 
        free(result.events); 
    }
    if(respJson){
        free(respJson);
    }
    return -1;
}

static void extract_sn_and_devsn(const char *topic, char *sn, char *dev_sn) {
    const char *start;
    const char *end;

    // 找到第一部分的起始位置
    start = strchr(topic, '/') + 1; // 跳过"ipc/"
    end = strchr(start, '/'); // 找到下一个"/"
    strncpy(sn, start, end - start);
    sn[end - start] = '\0'; // 确保字符串以null结尾

    // 找到第二部分的起始位置
    start = strchr(end + 1, '/') + 1; // 跳过"bms/"
    end = strchr(start, '/'); // 找到下一个"/"
    strncpy(dev_sn, start, end - start);
    dev_sn[end - start] = '\0'; // 确保字符串以null结尾

	return ;
}

/**
 * @brief       查询消息处理
 * @param[in]   struct ipc_message *msg
 * @return      int
 * @retval      0:正常  !0:错误
 * @par         修改日志:
 * Date                Author     Description           \n
 * 2024-02-18           JHC        创建初始版本          \n
*/
int event_query_alarm(struct ipc_message *msg)
{
	if(msg == NULL){ 
        return -1; 
    }
	struct alarm_filter info = {0};
    JsonValue result;
	char jsonpath1[128] = {0}, jsonpath2[128] = {0};
	int i,j,ret;
	void *jsonItem = get_jsonItem_by_msgContent((char *)msg->p.buf);

	if(jsonItem == NULL){ 
        return -1; 
    }
	extract_sn_and_devsn(msg->t.name,info.sn,info.dev_sn);
	json_value_get_by_json(jsonItem, "mi", &result);
    info.mi = result.int64Val;
	eventprocess_get_json_int_value(jsonItem,"page",&info.page);
	eventprocess_get_json_int_value(jsonItem,"size",&info.page_size);
	//解析各个堆的筛选条件
	info.bank_filter_num = json_get_array_length_by_json(jsonItem,"frames.lotBank");
    //加一下保护,防止变为复数在参数for循环
    info.bank_filter_num = (info.bank_filter_num > 0 ? info.bank_filter_num : 0);
	for(i=0; i<info.bank_filter_num; i++){
		snprintf(jsonpath1, sizeof(jsonpath1), "frames.lotBank[%d].bank", i);
		eventprocess_get_json_int_value(jsonItem,jsonpath1,&info.lot_bank[i].bank_id);
		snprintf(jsonpath2, sizeof(jsonpath2), "frames.lotBank[%d].locationNum", i);
		info.lot_bank[i].location_dev_num = json_get_array_length_by_json(jsonItem,jsonpath2);
		for(j=0; j<info.lot_bank[i].location_dev_num; j++){
            snprintf(jsonpath2, sizeof(jsonpath2), "frames.lotBank[%d].locationNum[%d]", i, j);
			eventprocess_get_json_int_value(jsonItem,jsonpath2,&info.lot_bank[i].location_num[j]);
		}
	}
	//解析筛选的level
	memset(jsonpath1,0,sizeof(jsonpath1));
	info.level_num = json_get_array_length_by_json(jsonItem,"frames.level");
    //加一下保护,防止变为复数在参数for循环
    info.level_num = (info.level_num > 0 ? info.level_num : 0);
	for(i = 0; i < info.level_num; i++){
		snprintf(jsonpath1, sizeof(jsonpath1), "frames.level[%d]", i);
		eventprocess_get_json_int_value(jsonItem,jsonpath1,&info.level[i]);
	}
	//解析筛选的舱ID
	memset(jsonpath1,0,sizeof(jsonpath1));
	info.continer_filter_num = json_get_array_length_by_json(jsonItem,"frames.containers");
    //加一下保护,防止变为复数在参数for循环
    info.continer_filter_num = (info.continer_filter_num > 0 ? info.continer_filter_num : 0);
	for(i = 0; i < info.continer_filter_num; i++){
		snprintf(jsonpath1, sizeof(jsonpath1), "frames.containers[%d]", i);
		eventprocess_get_json_int_value(jsonItem,jsonpath1,&info.continer_filter_array[i]);
	}
    ret = json_value_get_by_json(jsonItem, "frames.startTime", &result);
    if (0 == ret && result.type == JSON_VALUE_NUMBER) {
        info.start_time = result.int64Val;
    }

    ret = json_value_get_by_json(jsonItem, "frames.endTime", &result);
    if (0 == ret && result.type == JSON_VALUE_NUMBER) {
        info.end_time = result.int64Val;
    }

	//根据报文解析结果，进行数据库查询以及消息回复
	if(strstr(msg->t.name,"ImmediateAlarm")){
		immediate_alarm_query(&info);
	}
	else if(strstr(msg->t.name,"HistoryAlarm")){
		history_alarm_query(&info);
	}
	else if(strstr(msg->t.name,"DtcHistory")){
		history_dtc_query(&info);
	}

end:
	free_jsonItem(jsonItem);
	return 0;
}

int event_query_alarm_count(struct ipc_message *msg)
{
	if(msg == NULL){ 
        return -1; 
    }
    JsonValue result;
    char sn[SN_MAX_LEN];
	void *jsonItem = get_jsonItem_by_msgContent((char *)msg->p.buf);
    char *jsonString = NULL;
    struct ipc_topic t = {0};
    struct ipc_payload p = {0};
    char name[NAME_MAX_LEN] = {0};
    int rc = 0, history_counts = 0,immediate_counts = 0;
    long long mi = 0;
	if(jsonItem == NULL){ 
        return -1; 
    }
    bmser_dev_get_board_sn_ex(sn,SN_MAX_LEN);
    
    //获取历史告警总条数
    rc = sqlite3_exec(g_eventdb, "SELECT count(*) FROM alarm where clrtime > 0", rows_callback, &history_counts, NULL);
    if (rc != SQLITE_OK) {
        dy_syslog(LOG_ERR, "history alarm counts query error:%s\n",sqlite3_errmsg(g_eventdb));
        goto err;
    }
    rc = sqlite3_exec(g_eventdb, "SELECT count(*) FROM alarm where clrtime = 0", rows_callback, &immediate_counts, NULL);
    if (rc != SQLITE_OK) {
        dy_syslog(LOG_ERR, "history alarm counts query error:%s\n",sqlite3_errmsg(g_eventdb));
        goto err;
    }
	json_value_get_by_json(jsonItem, "mi", &result);
    mi = result.int64Val;

    cJSON *root = cJSON_CreateObject();
    cJSON *tags = cJSON_CreateObject();
    cJSON_AddStringToObject(root, "identifier", "AlarmCount");
    cJSON_AddNumberToObject(root, "time", (double)time(NULL));
    cJSON_AddNumberToObject(root, "mi", mi);
    cJSON_AddStringToObject(root, "sn", sn);
    cJSON_AddNumberToObject(tags, "hist_alarm", history_counts);
    cJSON_AddNumberToObject(tags, "real_alarm", immediate_counts);
    cJSON_AddItemToObject(root, "tags", tags);  

    jsonString = cJSON_PrintUnformatted(root);
    if(jsonString != NULL){
        snprintf(name,NAME_MAX_LEN,"ipc/%s/bms/00000000/data/GetResp/AlarmCount",sn);
        t.name = name;
        p.buf = jsonString;
        p.len = strlen(jsonString);
        communication_publish(&t,&p);
        free(jsonString);
    }
    cJSON_Delete(root);  
    free_jsonItem(jsonItem);
    return 0;
err:
    if(jsonItem){
        free_jsonItem(jsonItem);
    }
    if(root){ 
        cJSON_Delete(root); 
    }
    if(jsonString){
        free(jsonString);
    }
    return -1;
}

int event_query_clean_alarm(struct ipc_message *msg)
{
	if(msg == NULL){ 
		return -1; 
	}
	char sn[SN_MAX_LEN] = {0};
	void *jsonItem = get_jsonItem_by_msgContent((char *)msg->p.buf);
	JsonValue json_result;
	bmser_dev_get_board_sn_ex(sn,SN_MAX_LEN);

	if(jsonItem == NULL){ 
        return -1; 
    }
	json_value_get_by_json(jsonItem, "mi", &json_result);

	cJSON *root = cJSON_CreateObject();
	cJSON_AddStringToObject(root, "identifier", "CleanAlarm");
	cJSON_AddNumberToObject(root, "time", (double)time(NULL));

	cJSON *tags = cJSON_CreateObject();
	cJSON *result = cJSON_CreateObject();
	if(0 == clean_alarm()){
		cJSON_AddBoolToObject(result, "Result", true);
	}
	else{
		cJSON_AddBoolToObject(result, "Result", false);
	}
    cJSON_AddItemToObject(root, "tags", tags);
    cJSON_AddNumberToObject(root, "mi", json_result.int64Val);

	char *jsonString = cJSON_PrintUnformatted(root);
	cJSON_Delete(root);

	{
		struct ipc_topic t = {0};
		struct ipc_payload p = {0};
		char name[NAME_MAX_LEN] = {0};

		snprintf(name,NAME_MAX_LEN,"ipc/%s/bms/00000000/data/SetResp/CleanAlarm",sn);
		t.name = name;

		p.buf = jsonString;
		p.len = strlen(jsonString);
		communication_publish(&t,&p);
		free(jsonString);
	}

	return 0;
}
