

#include "accident.h"
#include "define.h"


accident_control_t accident_control;

extern alarm_control_t alarm_control;

accident_info_t* match_accident_rule(uint32_t* alarm_code_array, uint32_t alarm_code_num, uint32_t alarm_code_cur);
int get_accident_rule_from_file(void);
#ifdef EN_TDENGINE
static int init_alarm_event_queue(accident_control_t* accident_control)
{
    INIT_LIST_HEAD(&accident_control->alarm_event_list);
    pthread_mutex_init(&accident_control->alarm_event_list_mutex, NULL);
    accident_control->alarm_event_list_max_size = 200;
    accident_control->alarm_event_list_size     = 0;
    return 0;
}

int accident_rule_Init(accident_control_t* accident_control)
{
    // 初始化告警事件队列
    int ret = init_alarm_event_queue(accident_control);
    if (ret != 0)
    {
        ems_syslog(LOG_ERR, "[zxf]init alarm event queue failed");
        return -1;
    }

    // 从配置文件中读取事故规则列表
    get_accident_rule_from_file();
    return 0;
}

int accident_control_destory(accident_control_t* accident_control)
{
    alarm_event_t* alarm_event = NULL;
    // 清空告警事件队列
    list_for_each_entry(alarm_event, &accident_control->alarm_event_list, list)
    {
        list_del(&alarm_event->list);
        free(alarm_event);
    }

    return 0;
}

alarm_event_t* create_alarm_event_node(alarm_real_t *real)
{
    alarm_event_t* alarm_event = (alarm_event_t*)malloc(sizeof(alarm_event_t));
    if (alarm_event == NULL)
    {
        ems_syslog(LOG_ERR, "[zxf]malloc alarm event struct failed");
        return NULL;
    }
    alarm_event->alarm_code = real->alarm->alarm_code;
    return alarm_event;
}

int push_alarm_event_to_queue(alarm_event_t* alarm_event)
{
    int ret = -1;
    pthread_mutex_lock(&accident_control.alarm_event_list_mutex);
    if (accident_control.alarm_event_list_size < accident_control.alarm_event_list_max_size)
    {
        list_add_tail(&alarm_event->list, &accident_control.alarm_event_list);
        accident_control.alarm_event_list_size++;
        ret = 0;
    }
    pthread_mutex_unlock(&accident_control.alarm_event_list_mutex);
    return ret;
}

alarm_event_t* peek_alarm_event_from_queue(void)
{
    alarm_event_t *event = NULL;
    pthread_mutex_lock(&accident_control.alarm_event_list_mutex);

    if (accident_control.alarm_event_list_size > 0)
    {
        event = list_first_entry(&accident_control.alarm_event_list, alarm_event_t, list);
    }

    pthread_mutex_unlock(&accident_control.alarm_event_list_mutex);
    return event;
}

alarm_event_t* pop_alarm_event_from_queue(void)
{
    alarm_event_t *event = NULL;
    pthread_mutex_lock(&accident_control.alarm_event_list_mutex);

    if (accident_control.alarm_event_list_size > 0) {
        // 获取头部元素
        struct list_head *node = accident_control.alarm_event_list.next;
        event = list_entry(node, alarm_event_t, list);
        
        // 从链表中移除
        list_del(node);
        accident_control.alarm_event_list_size--;
    }

    pthread_mutex_unlock(&accident_control.alarm_event_list_mutex);
    return event;
}

// 获取当前告警队列的所有告警ID
static uint32_t* get_all_alarm_codes(uint32_t* alarm_code_num)
{
    uint32_t* alarm_codes = NULL;
    *alarm_code_num = 0;
    
    pthread_mutex_lock(&alarm_control.alarm_real_list_mutex);
    
    if (alarm_control.alarm_real_list_size > 0) 
    {
        alarm_codes = (uint32_t*)malloc(alarm_control.alarm_real_list_size * sizeof(uint32_t));
        if (alarm_codes != NULL) 
        {
            int index = 0;
            alarm_real_t* pos = NULL;
            list_for_each_entry(pos, &alarm_control.alarm_real_list, list) 
            {
                alarm_codes[index++] = pos->alarm->alarm_code;
            }
        }
    }

    *alarm_code_num = alarm_control.alarm_real_list_size;
    
    pthread_mutex_unlock(&alarm_control.alarm_real_list_mutex);
    
    return alarm_codes;
}

void process_alarm_event_raise(void)
{
    uint32_t* alarm_codes_array = NULL;
    uint32_t alarm_codes_num = 0;
    if(accident_control.alarm_event_list_size > 0)
    {
        // 将当前告警队列的所有告警ID组装为数组
        alarm_codes_array = get_all_alarm_codes(&alarm_codes_num);
        if(alarm_codes_num == 0 || alarm_codes_array == NULL)
        {
            ems_syslog(LOG_ERR, "[zxf]get alarm codes failed");
            return;
        }
    }

    while(accident_control.alarm_event_list_size > 0)
    {
        accident_info_t* accident_info = NULL;

        alarm_event_t* alarm_event_real = pop_alarm_event_from_queue();
		if (alarm_event_real == NULL)
			continue;
        
        // 事故规则筛选
        accident_info = match_accident_rule(alarm_codes_array, alarm_codes_num, alarm_event_real->alarm_code);
        if(accident_info)
        {
            // 调用事故API
            accident_record_api(accident_info->alarm_code, accident_info->time[0], accident_info->time[1]);

            free(accident_info);
        }
		free(alarm_event_real);
    }

    if(alarm_codes_array)
    {
        free(alarm_codes_array);
    }
}

// 告警事件筛选处理线程
static void* accident_alarm_event_thread(void* arg)
{
    sleep(20);
    while (true)
    {
        usleep(500);
        // 告警事件处理
        process_alarm_event_raise();

    }
    return NULL;
}

// test 测试规则匹配
void test_match_rule(uint32_t* alarm_arrary, uint32_t alarm_num, uint32_t alarm_cur)
{
        accident_info_t* accident_info = NULL;
        
        // 事故规则筛选
        accident_info = match_accident_rule(alarm_arrary, alarm_num, alarm_cur);
        if(accident_info)
        {
            ems_syslog(LOG_WARNING, "[zxf]test match rule ID:%d, time:[%d,%d]",accident_info->alarm_code, accident_info->time[0], accident_info->time[1]);
            // 调用事故API
            free(accident_info);
        }
        else
        {
            ems_syslog(LOG_WARNING, "[zxf]not match");
        }
}

void test_match_rule_main(void)
{
    ems_syslog(LOG_WARNING, "[zxf]rule count: %d", accident_control.accident_rule_count);
    uint32_t code_ary_test1[7] = {1016, 1078, 12, 1515, 18, 1077, 1102};
    uint32_t code_ary_test2[4] = {1088, 20, 53, 1077};
    uint32_t code_ary_test3[4] = {1088, 2020, 5314, 1087};
    uint32_t code_ary_test4[3] = {1016, 1092, 1102};
    uint32_t code_ary_test5[4] = {1024, 2010, 1145, 1055};

    test_match_rule(code_ary_test1, 7, 1102);
    test_match_rule(code_ary_test1, 7, 1515);
    test_match_rule(code_ary_test1, 7, 1016);
    test_match_rule(code_ary_test1, 7, 1077);
    test_match_rule(code_ary_test2, 4, 1077);
    test_match_rule(code_ary_test2, 4, 1088);
    test_match_rule(code_ary_test2, 4, 30);
    test_match_rule(code_ary_test3, 4, 1088);
    test_match_rule(code_ary_test4, 3, 1102);
    test_match_rule(code_ary_test4, 3, 1092);
    test_match_rule(code_ary_test5, 4, 1055);
    test_match_rule(code_ary_test5, 4, 1145);
}

//  入口
int init_accident_control_task(void)
{
    // 初始化事件模块
    int ret = accident_rule_Init(&accident_control);
    if (ret != 0)
    {
        accident_control_destory(&accident_control);
        ems_syslog(LOG_ERR, "[zxf]accident control init failed");
        return ret;
    }

    // test_match_rule_main();

    pthread_t tid;
    if (pthread_create(&tid, NULL, accident_alarm_event_thread, NULL) != 0)
    {
        accident_control_destory(&accident_control);
        ems_syslog(LOG_ERR, "[zxf]accident alarm event thread init failed");
        return -1;
    }
    else
    {
        pthread_setname_np(tid, "accident_event");
    }
    return 0;
}

static bool is_valid_accident_rule(char *expr) 
{
    int len = strlen(expr);
    int paren_count = 0;
    bool expect_operand = true; // 期望是否跟操作数
    bool last_was_operator = false;
    // bool last_was_space = false;

    for (int i = 0; i < len; i++) 
    {
        char c = expr[i];

        // 跳过空格
        if (isspace(c)) 
        {
            // last_was_space = true;
            continue;
        }

        // 检查括号
        if (c == '(') 
        {
            if (!expect_operand) 
            {
                return false; // 运算符后不能直接跟 '('
            }
            paren_count++;
            expect_operand = true; // 括号后需要操作数
            last_was_operator = false;
        }
        else if (c == ')') 
        {
            if (expect_operand || paren_count <= 0) 
            {
                return false; // 不能以 ) 开头或括号不匹配
            }
            paren_count--;
            expect_operand = false; // ) 后需要运算符
            last_was_operator = false;
        }
        // 检查运算符
        else if (c == '&' || c == '|') 
        {
            if (expect_operand) 
            {
                return false; // 不能以运算符开头
            }
            // 检查完整运算符 (&& 或 ||)
            if (i + 1 >= len || expr[i+1] != c) 
            {
                return false;
            }
            i++; // 跳过第二个字符
            expect_operand = true; // 运算符后需要操作数
            last_was_operator = true;
        }
        // 检查操作数 (数字)
        else if (isdigit(c)) 
        {
            if (!expect_operand) 
            {
                return false; // 不期望操作数时出现数字
            }
            // 读取完整数字
            while (i < len && isdigit(expr[i])) 
            {
                i++;
            }
            i--;
            expect_operand = false; // 数字后需要运算符
            last_was_operator = false;
        } 
        else 
        {
            return false; // 非法字符
        }
        
        // last_was_space = false;
    }

    // 检查括号是否匹配且不以运算符结尾
    return (paren_count == 0) && !expect_operand && !last_was_operator;
}

// 解析事故规则json
int deal_accident_rule_config(cJSON *root)
{
    cJSON *result = cJSON_GetObjectItem(root, "result");
    if(!result || !cJSON_IsArray(result))
    {
        ems_syslog(LOG_ERR, "[zxf]accident no result!");
        return 2;
    }
    cJSON *interval = cJSON_GetObjectItemCaseSensitive(root, "interval");
    if (!cJSON_IsNumber(interval)) {
        ems_syslog(LOG_ERR,"no find interval\n");
    } else {
        dev_set_dev_tag_int(DEV_NO_EMS, ACCIDENT_TGI, interval->valueint);  // 写值
    }
// "interval":1，//上报的事故数据时间间隔


    int array_size = cJSON_GetArraySize(result);
    accident_rule_t* new_rules = (accident_rule_t*)malloc(array_size * sizeof(accident_rule_t));
    if (!new_rules)
    {
        ems_syslog(LOG_ERR, "[zxf]malloc accident rule struct failed");
        return 2;
    }

    for (int i = 0; i < array_size; i++)
    {
        cJSON *item = cJSON_GetArrayItem(result, i);
        if (!item) continue;

        cJSON *id_item = cJSON_GetObjectItem(item, "id");
        if (!id_item)
        {
            ems_syslog(LOG_ERR, "[zxf]accident no id!");
            free(new_rules);
            return 2;
        }

        cJSON *name_item = cJSON_GetObjectItem(item, "name");
        if (!name_item)
        {
            ems_syslog(LOG_ERR, "[zxf]accident no name!");
            free(new_rules);
            return 2;
        }

        cJSON *time_before_item = cJSON_GetObjectItem(item, "timeBefore");
        if (!time_before_item)
        {
            ems_syslog(LOG_ERR, "[zxf]accident no timeBefore!");
            free(new_rules);
            return 2;
        }


        cJSON *time_after_item = cJSON_GetObjectItem(item, "timeAfter");
        if (!time_after_item)
        {
            ems_syslog(LOG_ERR, "[zxf]accident no timeAfter!");
            free(new_rules);
            return 2;
        }

        cJSON *rule_item = cJSON_GetObjectItem(item, "rule");
        if(!rule_item)
        {
            ems_syslog(LOG_ERR, "[zxf]accident no rule!");
            free(new_rules);
            return 2;
        }

        if(!is_valid_accident_rule(rule_item->valuestring))
        {
            ems_syslog(LOG_ERR, "[zxf]accident rule[%d] is not valid!", id_item->valueint);
            free(new_rules);
            return 1;
        }

        new_rules[i].id = i;
        new_rules[i].time[0] = time_before_item->valueint;
        new_rules[i].time[1] = time_after_item->valueint;

        new_rules[i].name = strdup(name_item->valuestring);
        new_rules[i].rule = strdup(rule_item->valuestring);
        ems_syslog(LOG_WARNING, "[zxf]emms2get accident config ID:%d, name:[%s], time:[%d,%d], rule:[%s]",new_rules[i].id, new_rules[i].name, new_rules[i].time[0], new_rules[i].time[1], new_rules[i].rule);
    }

    // 先释放旧的规则
    if(accident_control.accident_rule)
    {
        for (int i = 0; i < accident_control.accident_rule_count; i++) {
            if (accident_control.accident_rule[i].name) {
                free(accident_control.accident_rule[i].name);
            }
            if (accident_control.accident_rule[i].rule) {
                free(accident_control.accident_rule[i].rule);
            }
        }
        free(accident_control.accident_rule);
    }

    accident_control.accident_rule = new_rules;
    accident_control.accident_rule_count = array_size;

    return 0;
}

// 保存规则配置文件
int save_accident_rule_config_file(cJSON *root)
{
    if (!root) 
    {
        ems_syslog(LOG_ERR, "[zxf]save accident rule json: input json is null");
        return -1;
    }

    char *json_str = cJSON_Print(root);
    if (!json_str) 
    {
        ems_syslog(LOG_ERR, "[zxf]save accident rule json: cJSON_Print failed");
        return -1;
    }


    // 写入文件
    int ret = write_file_data(ACCIDENT_RULE_CONFIG_FILE, json_str, strlen(json_str));
    if (ret != 0) 
    {
        ems_syslog(LOG_ERR, "[zxf]save accident rule json: write file failed");
    }

    free(json_str);
    
    return ret;
}

int get_accident_rule_from_file(void)
{
    char*  file = NULL;
    cJSON* json = NULL;
    file        = read_file_data(ACCIDENT_RULE_CONFIG_FILE);
    if (file == NULL) 
    {
        ems_syslog(LOG_ERR, "[zxf]file emms2_accident_rule.json is NULL");
        goto ERR0;
    }

    json = cJSON_Parse(file);
    if (json == NULL)
    {
        ems_syslog(LOG_ERR, "[zxf]json parse fail");
        goto ERR0;
    }

    if (deal_accident_rule_config(json) != 0)
    {
        ems_syslog(LOG_ERR, "[zxf]Failed to process accident rules");
        goto ERR0;
    }

ERR0:
    if (file != NULL)
    {
        free(file);
    }
    if (json != NULL)
    {
        cJSON_Delete(json);
    }
    return 0;
}

// 辅助函数：检查告警码是否存在于数组
static bool code_exists(uint32_t code, uint32_t* codes, uint32_t code_num) 
{
    if (!codes || code_num == 0) return false;
    for (int i = 0; i < code_num; i++) 
    {
        if (codes[i] == code) 
            return true;
    }
    return false;
}

static Token* tokenize(const char* str, int* token_count) 
{
    int len = strlen(str);
    Token* tokens = malloc(len * sizeof(Token));
    int pos = 0, count = 0;
    
    while (pos < len) 
    {
        char c = str[pos];
        if (isspace(c)) 
        {
            pos++;
            continue;
        }
        
        if (isdigit(c)) 
        { // 解析数字
            uint32_t num = 0;
            while (pos < len && isdigit(str[pos])) 
            {
                num = num * 10 + (str[pos++] - '0');
            }
            tokens[count++] = (Token){TOKEN_NUM, num};
        }
        else if (c == '(') 
        {
            tokens[count++] = (Token){TOKEN_LPAREN, 0};
            pos++;
        } 
        else if (c == ')') 
        {
            tokens[count++] = (Token){TOKEN_RPAREN, 0};
            pos++;
        } 
        else if (c == '&' && pos+1 < len && str[pos+1] == '&') 
        {
            tokens[count++] = (Token){TOKEN_AND, 0};
            pos += 2;
        } 
        else if (c == '|' && pos+1 < len && str[pos+1] == '|') 
        {
            tokens[count++] = (Token){TOKEN_OR, 0};
            pos += 2;
        } 
        else 
        {
            free(tokens);
            return NULL;
        }
    }
    tokens[count++] = (Token){TOKEN_EOF, 0};
    *token_count = count;
    return tokens;
}

static bool parse_expr(Token* tokens, int* pos, uint32_t* codes, uint32_t code_num);
static bool parse_factor(Token* tokens, int* pos, uint32_t* codes, uint32_t code_num);

static bool parse_expr(Token* tokens, int* pos, uint32_t* codes, uint32_t code_num) 
{
    // ems_syslog(LOG_WARNING, "[zxf]enter parse_expr pos [%d]", *pos);
    bool left = parse_factor(tokens, pos, codes, code_num);
    while (tokens[*pos].type == TOKEN_AND) 
    {
        (*pos)++;
        left = left && parse_factor(tokens, pos, codes, code_num);
    }
    // ems_syslog(LOG_WARNING, "[zxf]parse_expr return [%d] pos [%d]",left, *pos);
    return left;
}

static bool parse_or(Token* tokens, int* pos, uint32_t* codes, uint32_t code_num) 
{
    // ems_syslog(LOG_WARNING, "[zxf]enter parse_or pos[%d]", *pos);
    bool left = parse_expr(tokens, pos, codes, code_num);
    // ems_syslog(LOG_WARNING, "[zxf]type=[%d], pos= [%d]", tokens[*pos].type, *pos);
    while (tokens[*pos].type == TOKEN_OR) 
    {
        // ems_syslog(LOG_WARNING, "[zxf]enter type == TOKEN_OR !!");
        (*pos)++;
        bool ret = parse_expr(tokens, pos, codes, code_num);
        // ems_syslog(LOG_WARNING, "[zxf]left[%d], ret[%d]",left,ret);
        left = left || ret;
    }
    // ems_syslog(LOG_WARNING, "[zxf]parse_or return [%d] pos [%d]",left, *pos);
    return left;
}

static bool parse_factor(Token* tokens, int* pos, uint32_t* codes, uint32_t code_num) 
{
    // ems_syslog(LOG_WARNING, "[zxf]enter parse_factor pos[%d]",*pos);
    if (tokens[*pos].type == TOKEN_LPAREN) 
    {
        // ems_syslog(LOG_WARNING, "[zxf]Entering parenthesis...");
        (*pos)++;
        bool res = parse_or(tokens, pos, codes, code_num);
        if (tokens[*pos].type != TOKEN_RPAREN) 
        {
            // ems_syslog(LOG_WARNING, "[zxf]Mismatched parenthesis pos[%d]",*pos);
            return false; // 括号不匹配
        }
        (*pos)++;
        // ems_syslog(LOG_WARNING, "[zxf]Exited parenthesis. Result: %d pos[%d]", res, *pos);
        return res;
    }
    if (tokens[*pos].type == TOKEN_NUM) 
    {
        uint32_t code = tokens[*pos].value;
        (*pos)++;
        bool exist_res = code_exists(code, codes, code_num);
        // ems_syslog(LOG_WARNING, "[zxf]TOKEN_NUM. Result: %d pos [%d]", exist_res, *pos);
        return exist_res;

    }
    // ems_syslog(LOG_WARNING, "[zxf]parse_factor return false pos [%d]",*pos);
    return false;
}

// 匹配事故规则函数
accident_info_t* match_accident_rule(uint32_t* alarm_code_array, uint32_t alarm_code_num, uint32_t alarm_code_cur) 
{
    for (int i = 0; i < accident_control.accident_rule_count; i++) 
    {
        accident_rule_t* rule = &accident_control.accident_rule[i];
        
        // 将规则字符串分解为操作符和告警码
        int token_count = 0;
        Token* tokens = tokenize(rule->rule, &token_count);
        if (!tokens) continue;
        
        // 检查当前告警码是否在事故规则中
        bool is_trigger_code_present = false;
        for (int j = 0; j < token_count; j++) 
        {
            if (tokens[j].type == TOKEN_NUM && tokens[j].value == alarm_code_cur) 
            {
                // ems_syslog(LOG_WARNING, "[zxf]test cur alarm code in rule");
                is_trigger_code_present = true;
                break;
            }
        }
        if (!is_trigger_code_present) 
        { 
            free(tokens);
            continue; 
        }

        // 递归解析器
        int pos = 0;
        bool match = parse_or(tokens, &pos, alarm_code_array, alarm_code_num);
        bool valid = match && (tokens[pos].type == TOKEN_EOF);
        free(tokens);
        
        if (valid) 
        {
            accident_info_t* info = malloc(sizeof(accident_info_t));
            info->alarm_code = rule->id;
            memcpy(info->time, rule->time, sizeof(rule->time));
            return info;
        }
    }
    return NULL;
}

#else

// static int init_alarm_event_queue(accident_control_t* accident_control)
// {return 0;}


int accident_rule_Init(accident_control_t* accident_control)
{return 0;}

int accident_control_destory(accident_control_t* accident_control)
{return 0;}

alarm_event_t* create_alarm_event_node(alarm_real_t *real)
{return NULL;}

int push_alarm_event_to_queue(alarm_event_t* alarm_event)
{return 0;}

alarm_event_t* peek_alarm_event_from_queue(void)
{return NULL;}

alarm_event_t* pop_alarm_event_from_queue(void)
{return NULL;}

// 获取当前告警队列的所有告警ID
// static uint32_t* get_all_alarm_codes(uint32_t* alarm_code_num)
// {return NULL;}

void process_alarm_event_raise(void)
{}

// // 告警事件筛选处理线程
// static void* accident_alarm_event_thread(void* arg)
// {return NULL;}

// test 测试规则匹配
void test_match_rule(uint32_t* alarm_arrary, uint32_t alarm_num, uint32_t alarm_cur)
{}

void test_match_rule_main(void)
{}

//  入口
int init_accident_control_task(void)
{return 0;}


// static bool is_valid_accident_rule(char *expr) 
// {return 0;}


// 解析事故规则json
int deal_accident_rule_config(cJSON *root)
{return 0;}

// 保存规则配置文件
int save_accident_rule_config_file(cJSON *root)
{return 0;}

// 从配置文件中读取事故规则
int get_accident_rule_from_file(void)
{return 0;}

// 辅助函数：检查告警码是否存在于数组
// static bool code_exists(uint32_t code, uint32_t* codes, uint32_t code_num) 
// {return 0;}

// static Token* tokenize(const char* str, int* token_count) 
// {return NULL;}

// static bool parse_expr(Token* tokens, int* pos, uint32_t* codes, uint32_t code_num);
// static bool parse_factor(Token* tokens, int* pos, uint32_t* codes, uint32_t code_num);

// static bool parse_expr(Token* tokens, int* pos, uint32_t* codes, uint32_t code_num) 
// {return 0;}

// static bool parse_or(Token* tokens, int* pos, uint32_t* codes, uint32_t code_num) 
// {return 0;}

// static bool parse_factor(Token* tokens, int* pos, uint32_t* codes, uint32_t code_num) 
// {
//     return 0;
// }

// 匹配事故规则函数
accident_info_t* match_accident_rule(uint32_t* alarm_code_array, uint32_t alarm_code_num, uint32_t alarm_code_cur) 
{
    return NULL;

}

#endif
