#include "rull.h"
#include "../common.h"
typedef struct
{
    double value;
    double last_value;
    double jump;
} rull_value_t;

// 使用线程局部存储避免竞争条件
static  rull_value_t g_rull_value;
// 定义tinyexpr变量
static  te_variable g_vars[] = {
    {"value", &g_rull_value.value, TE_VARIABLE, NULL},
    {"last_value", &g_rull_value.last_value, TE_VARIABLE, NULL},
    {"jump", &g_rull_value.jump, TE_VARIABLE, NULL}};

// #define TETEST
#ifdef TETEST
static int rull_eval(const char *expression, te_variable *vars, int var_count);
static int test1()
{
    const char *expression = "value == 1";

    g_rull_value.value = 1;
    // g_rull_value.value = 0;

    te_variable vars[] = {
        {"value", &g_rull_value.value, TE_VARIABLE, NULL},
    };
    int var_count = sizeof(vars) / sizeof(te_variable);
    int is_abnormal = rull_eval(expression, vars, var_count);
    return is_abnormal;
}

static int test2()
{
    // printf("test2 =====\n");
    const char *expression = "value<0 || value >1000";

    // g_rull_value.value = -20;
    // g_rull_value.value = 80;
    g_rull_value.value = 1002;

    static te_variable vars[] = {
        {"value", &g_rull_value.value, TE_VARIABLE, NULL},
    };
    int var_count = sizeof(vars) / sizeof(te_variable);

    int is_abnormal = rull_eval(expression, vars, var_count);
    printf("test2 = %d===\n", is_abnormal);

    return is_abnormal;
}

static int test3()
{
    const char *expression = "abs(jump)>last_value *0.2";

    // g_rull_value.value = 121;
    // g_rull_value.value = 81;
    g_rull_value.value = 79;

    g_rull_value.last_value = 100;
    g_rull_value.jump = g_rull_value.last_value - g_rull_value.value;

    static te_variable vars[] = {
        {"value", &g_rull_value.value, TE_VARIABLE, NULL},
        {"last_value", &g_rull_value.last_value, TE_VARIABLE, NULL},
        {"jump", &g_rull_value.jump, TE_VARIABLE, NULL}};
    int var_count = sizeof(vars) / sizeof(te_variable);

    int is_abnormal = rull_eval(expression, vars, var_count);

    return is_abnormal;
}

#endif

static int rull_eval(const char *expression, te_variable *vars, int var_count)
{
    int error_pos = 0;
    te_expr *expr = te_compile(expression, vars, var_count, &error_pos);

    if (!expr)
    {

        if (error_pos >= 0 && expression[error_pos] != '\0')
        {
            ems_syslog(LOG_ERR, "表达式解析错误 near position %d: '%.*s<HERE>%s'\n",
                   error_pos, error_pos, expression, expression + error_pos);
        }
        else
        {
            ems_syslog(LOG_ERR, "表达式解析错误 at position %d (可能已到字符串末尾)\n", error_pos);
        }

        return -1;
    }
    // printf("规则解析失败: %s, 错误码: %d,错误附近的字符可能是: %c\n", expression, error, expression[error]);

    // 执行规则判断
    double result = te_eval(expr);
    te_free(expr);

    // 规则结果为非0表示异常（true），0表示正常（false）
    int is_abnormal = (result != 0.0);

    if (is_abnormal)
    {
        // printf("规则判断异常! 规则: %s, 结果: %.2f\n", expression, result);
        // printf("当前值: %.2f, 上次值: %.2f, 跳变: %.2f\n", g_rull_value.value, g_rull_value.last_value, g_rull_value.jump);
    }
    return is_abnormal;
}

int rull_process(abnormal_point_t *matched_point, tag_t *tag)
{
    if (!matched_point || !tag || !matched_point->rule)
    {
        ems_syslog(LOG_ERR, "参数错误! 规则: %s, 标签: %s\n", 
               matched_point ? matched_point->rule : "NULL", 
               tag ? tag->name : "NULL");
        return -1;
    }
        // 验证数据类型
    if (tag->data_type != TYPE_TAG_INT && tag->data_type != TYPE_TAG_FLOAT)
    {
        ems_syslog(LOG_ERR, "不支持的数据类型: %d, 标签: %s\n", tag->data_type, tag->name);
        return -1;
    }
    
    // 验证规则表达式不为空
    if (strlen(matched_point->rule) == 0)
    {
        ems_syslog(LOG_ERR, "规则表达式为空, 标签: %s\n", tag->name);
        return -1;
    }
    /*******************************所有规则变量初始化*************************/
    if (tag->data_type == TYPE_TAG_INT)
    {
        g_rull_value.value = (double)tag->read_cache.to_int;
        g_rull_value.last_value = (double)tag->last_read_cache.to_int;
    }
    else
    {
        g_rull_value.value = tag->read_cache.to_float;
        g_rull_value.last_value = tag->last_read_cache.to_float;
    }

    // 计算跳变值
    g_rull_value.jump = g_rull_value.value - g_rull_value.last_value;

    int is_abnormal = rull_eval(matched_point->rule, g_vars, sizeof(g_vars) / sizeof(te_variable));
    // if (is_abnormal)
    //     printf("value = %f, last_value = %f, jump = %f\n", g_rull_value.value, g_rull_value.last_value, g_rull_value.jump);

    /**************************************************************************/
#ifdef TETEST
#if 0
    test1();
#endif
#if 0
    test2();
#endif

#if 0
    test3();
#endif
#endif
    /**************************************************************************/

    return is_abnormal;
}
