#include "automatic.h"
#include "../tag.h"
#include <math.h>
#include "../proto_forward.h"
#ifndef EN_EMS
#include "../ems/deviceLayer.h"
#else
#include "../lc/deviceLayer.h"
#endif
#include "define.h"
#include "../alarm_control/alarm_control.h"
/************************************************************动环***************************************************************/
int rull_index = 0;
AUTOMATIC_INFO *auto_matic_info = NULL;
char *condition_type_string[] = {
    ">",
    ">=",
    "=",
    "<",
    "<=",
};

AUTOMATIC_CONDITION get_condition_by_string(char *conditionString)
{
    if (conditionString==NULL)
    {
        return AUTOMATIC_CONDITION_ERROR;
    }
    for (AUTOMATIC_CONDITION i = AUTOMATIC_CONDITION_GT ; i < AUTOMATIC_CONDITION_MAX ; i++)
    {
        if(strcmp(conditionString,condition_type_string[i])==0)
        return i;
    }
    proto_syslog(LOG_WARNING, "CONDITION get ERROR");
    return AUTOMATIC_CONDITION_ERROR;
}



bool check_tag_value_int(AUTOMATIC_CONDITION condition,tag_t *tag,int value,tag_t *value_is_tag)
{
    float name_tag = 0;
    float value_tag = 0;

    if(value_is_tag != NULL) //value是点位
    {
        switch (condition)
        {
            case AUTOMATIC_CONDITION_GT:
            {
                if(tag->data_type == TYPE_TAG_INT && value_is_tag->data_type == TYPE_TAG_INT)
                {
                    if(tag->read_cache.to_int > value_is_tag->read_cache.to_int)
                        return true;
                }
                else
                {
                    name_tag = (tag->data_type == TYPE_TAG_FLOAT) ? tag->read_cache.to_float : (float)tag->read_cache.to_int;
                    value_tag = (value_is_tag->data_type == TYPE_TAG_FLOAT) ? value_is_tag->read_cache.to_float : (float)value_is_tag->read_cache.to_int;
                    if((name_tag - value_tag) > 0.001)
                        return true;
                }
            }
            break;
            case AUTOMATIC_CONDITION_GE:
            {
                if(tag->data_type == TYPE_TAG_INT && value_is_tag->data_type == TYPE_TAG_INT)
                {
                    if(tag->read_cache.to_int >= value_is_tag->read_cache.to_int)
                        return true;
                }
                else
                {
                    name_tag = (tag->data_type == TYPE_TAG_FLOAT) ? tag->read_cache.to_float : (float)tag->read_cache.to_int;
                    value_tag = (value_is_tag->data_type == TYPE_TAG_FLOAT) ? value_is_tag->read_cache.to_float : (float)value_is_tag->read_cache.to_int;
                    if((name_tag - value_tag) >= -0.001)
                        return true;
                }
            }
            break;
            case AUTOMATIC_CONDITION_EQ:
            {
                if(tag->data_type == TYPE_TAG_INT && value_is_tag->data_type == TYPE_TAG_INT)
                {
                    if(tag->read_cache.to_int == value_is_tag->read_cache.to_int)
                        return true;
                }
                else
                {
                    name_tag = (tag->data_type == TYPE_TAG_FLOAT) ? tag->read_cache.to_float : (float)tag->read_cache.to_int;
                    value_tag = (value_is_tag->data_type == TYPE_TAG_FLOAT) ? value_is_tag->read_cache.to_float : (float)value_is_tag->read_cache.to_int;
                    if((name_tag - value_tag) < 0.001)
                        return true;
                }
            }
            break;
            case AUTOMATIC_CONDITION_LT:
            {
                if(tag->data_type == TYPE_TAG_INT && value_is_tag->data_type == TYPE_TAG_INT)
                {
                    if(tag->read_cache.to_int < value_is_tag->read_cache.to_int)
                        return true;
                }
                else
                {
                    name_tag = (tag->data_type == TYPE_TAG_FLOAT) ? tag->read_cache.to_float : (float)tag->read_cache.to_int;
                    value_tag = (value_is_tag->data_type == TYPE_TAG_FLOAT) ? value_is_tag->read_cache.to_float : (float)value_is_tag->read_cache.to_int;
                    if((name_tag - value_tag) < -0.001)
                        return true;
                }
            }
            break;
            case AUTOMATIC_CONDITION_LE:
            {
                if(tag->data_type == TYPE_TAG_INT && value_is_tag->data_type == TYPE_TAG_INT)
                {
                    if(tag->read_cache.to_int <= value_is_tag->read_cache.to_int)
                        return true;
                }
                else
                {
                    name_tag = (tag->data_type == TYPE_TAG_FLOAT) ? tag->read_cache.to_float : (float)tag->read_cache.to_int;
                    value_tag = (value_is_tag->data_type == TYPE_TAG_FLOAT) ? value_is_tag->read_cache.to_float : (float)value_is_tag->read_cache.to_int;
                    if((name_tag - value_tag) <= 0.001)
                        return true;
                }
            }
            break;
            default:
            break;
        }
    }
    else
    {
        switch (condition)
        {
            case AUTOMATIC_CONDITION_GT:
            {
                if(tag->data_type == TYPE_TAG_INT)
                {
                    if(tag->read_cache.to_int > value)
                        return true;
                }
                else 
                {
                    if((tag->read_cache.to_float - value)>0.001)
                        return true;
                }   
            }
            break;
            case AUTOMATIC_CONDITION_GE:
            {
                if(tag->data_type == TYPE_TAG_INT)
                {
                    if(tag->read_cache.to_int >= value)
                        return true;
                }
                else 
                {
                    if((tag->read_cache.to_float - value)>=-0.001)
                        return true;
                }   
            }
            break;
            case AUTOMATIC_CONDITION_EQ:
            {
                if(tag->data_type == TYPE_TAG_INT)
                {
                    if(tag->read_cache.to_int == value)
                        return true;
                }
                else 
                {
                    if(fabs(tag->read_cache.to_float - value) < 0.001)
                        return true;
                }   
            }
            break;
            case AUTOMATIC_CONDITION_LT:
            {
                if(tag->data_type == TYPE_TAG_INT)
                {
                    if(tag->read_cache.to_int < value)
                        return true;
                }
                else 
                {
                    if((tag->read_cache.to_float - value)<-0.001)
                        return true;
                }   
            }
            break;
            case AUTOMATIC_CONDITION_LE:
            {
                if(tag->data_type == TYPE_TAG_INT)
                {
                    if(tag->read_cache.to_int <= value)
                        return true;
                }
                else 
                {
                    if((tag->read_cache.to_float - value)<=0.001)
                        return true;
                }   
            }
            break;
            default:
            break;
        }
    }
    
    return false;
}

bool tag_compare(tag_t *tag_tmp, tag_t *tag)
{
    if (strcmp(tag_tmp->dev_tag_name,tag->dev_tag_name)==0)
    {
        return true;
    }
    return false;
}

void clean_stop_state()
{
    for (size_t i = 0; i < rull_index; i++)
    {
        for (size_t j = 0; j < auto_matic_info[i].condition_index; j++)
        {
            for (size_t k = 0; k < auto_matic_info[i].conditionInfo[j]->conditionList_index; k++)
            {
                auto_matic_info[i].conditionInfo[j]->condition_or_info[k]->striggered = false;
                ems_syslog(LOG_WARNING, "clean %s striggered!",auto_matic_info[i].name);
            } 
        }
    }
}
//遍历所有   当触发过了 且所在的与条件中符合要求 需要返回再次执行触发值 否则返回不在触发；  如果没触发过且满足触发条件则触发并设置触发标志位  ；AUTOMATIC_MODE_DEFAULT模式的按顺序优先级触发当一个触发则后续的不再触发
//当有触发 优先触发不可恢复的并且设置触发状态 数组前面的优先级高
bool checkConditionList(AUTOMATIC_INFO *automatic_info,int *distvalue,tag_t *tag_this)
{
    int mode_actVal_value = 0;//用于获取actVal值
    bool condition_matched = false;//用于逻辑控制for循环和判断是否使用restValue重置值
    bool trigger_tag = false;
    bool currue_tag_trigger = false;
    tag_t *tag;
    for (size_t i = 0; i < automatic_info->condition_index; i++)
    {
        for (size_t j = 0; j < automatic_info->conditionInfo[i]->conditionList_index; j++)
        {
            switch (automatic_info->conditionInfo[i]->condition_or_info[j]->mode)
            {
            case AUTOMATIC_MODE_REPEAT:
            case AUTOMATIC_MODE_DEFAULT:
                {
                    if (condition_matched)
                    {
                        continue;
                    }
                    bool result = true;
                    size_t k = 0;
                    for (k = 0; k < automatic_info->conditionInfo[i]->condition_or_info[j]->conditionAnd_index; k++)
                    {
                        tag = automatic_info->conditionInfo[i]->condition_or_info[j]->condition_and_info[k]->tag;
                        if (tag)
                        {
                            int tag_flag = 0;
                            if (strcmp(tag->dev_tag_name, tag_this->dev_tag_name) == 0) // 如果是同一个tag，就使用备份,解决写tag是一个备份的问题(传入的tag_this是指向一个备份，里面有最新的写数据)
                            {
                                tag = tag_this;
                                tag_flag = 1;
                            }
                            int ret = 0;
                            if(automatic_info->conditionInfo[i]->condition_or_info[j]->condition_and_info[k]->value_is_tag != NULL)
                            {
                                ret = check_tag_value_int(automatic_info->conditionInfo[i]->condition_or_info[j]->condition_and_info[k]->condition, tag, 0, automatic_info->conditionInfo[i]->condition_or_info[j]->condition_and_info[k]->value_is_tag);                          
                            }
                            else
                            {
                                ret = check_tag_value_int(automatic_info->conditionInfo[i]->condition_or_info[j]->condition_and_info[k]->condition, tag, automatic_info->conditionInfo[i]->condition_or_info[j]->condition_and_info[k]->value, NULL);                           
                            }
                            
                            CONDITION_AND_INFO *cond_info = automatic_info->conditionInfo[i]->condition_or_info[j]->condition_and_info[k];
                            if (cond_info->debounceTime > 0) 
                            {
                                if (ret) 
                                {        
                                    if (tag_flag == 1)        
                                    {
                                        cond_info->debounceCount++;      
                                        ems_syslog(LOG_INFO, "debounce count for [%s]: %d/%d", tag->dev_tag_name, cond_info->debounceCount, cond_info->debounceTime);  
                                    }                                                                                                                    
                                    if (cond_info->debounceCount >= cond_info->debounceTime) 
                                    {
                                        ret = 1;
                                    } 
                                    else
                                    {
                                        ret = 0; 
                                    }
                                } 
                                else 
                                {
                                    cond_info->debounceCount = 0;
                                    ret = 0;
                                    ems_syslog(LOG_INFO, "debounce count for [%s]: %d/%d", tag->dev_tag_name, cond_info->debounceCount, cond_info->debounceTime);
                                }
                            }
                            result &= ret;
                            if (ret&&tag_compare(tag_this, tag))
                            {
                                trigger_tag = true;
                            }
                            
                            ems_syslog(LOG_INFO, "get [%s] result %d ", tag->dev_tag_name, result);
                        }
                        else
                        {
                            ems_syslog(LOG_ERR, "tag is NULL!");
                        }                        
                    }

                    if (k > 0)
                    {
                        if (result)
                        {
                            if(trigger_tag)
                            {
                                mode_actVal_value = automatic_info->conditionInfo[i]->actVal;
                                condition_matched = true;                               
                            }
                            else
                            {
                                currue_tag_trigger = true;
                            }
                        }  
                        else
                        {
                            condition_matched = false;
                        }  
                    }
                }
                break;
            case AUTOMATIC_MODE_STOP:
                {
                    if (automatic_info->conditionInfo[i]->condition_or_info[j]->striggered == true)
                    {
                        ems_syslog(LOG_WARNING, "stop mode  %s striggered!",automatic_info->name);
                        return false;
                    }
                    else
                    {
                        if (condition_matched)
                        {
                            continue;
                        }
                        bool result = true;
                        size_t k = 0;
                        for (k = 0; k < automatic_info->conditionInfo[i]->condition_or_info[j]->conditionAnd_index; k++)
                        {
                            tag = automatic_info->conditionInfo[i]->condition_or_info[j]->condition_and_info[k]->tag;
                            if (tag)
                            {
                                if (strcmp(tag->name, tag_this->name) == 0) // 如果是同一个tag，就使用备份,解决写tag是一个备份的问题(传入的tag_this是指向一个备份，里面有最新的写数据)
                                {
                                    tag = tag_this;
                                }
                                int ret = 0;
                                if(automatic_info->conditionInfo[i]->condition_or_info[j]->condition_and_info[k]->value_is_tag != NULL)
                                {
                                    ret = check_tag_value_int(automatic_info->conditionInfo[i]->condition_or_info[j]->condition_and_info[k]->condition, tag, 0, automatic_info->conditionInfo[i]->condition_or_info[j]->condition_and_info[k]->value_is_tag);                          
                                }
                                else
                                {
                                    ret = check_tag_value_int(automatic_info->conditionInfo[i]->condition_or_info[j]->condition_and_info[k]->condition, tag, automatic_info->conditionInfo[i]->condition_or_info[j]->condition_and_info[k]->value, NULL);                           
                                }
                                result &= ret;
                                if (ret&&tag_compare(tag_this, tag))
                                {
                                    trigger_tag = true;
                                }
                                
                                ems_syslog(LOG_INFO, "get [%s] result %d ", tag->dev_tag_name, result);
                            }
                            else
                            {
                                ems_syslog(LOG_ERR, "tag is NULL!");
                            }                        
                        }

                        if (k > 0)
                        {
                            if (result)
                            {
                                if(trigger_tag)
                                {
                                    mode_actVal_value = automatic_info->conditionInfo[i]->actVal;
                                    automatic_info->conditionInfo[i]->condition_or_info[j]->striggered = true;
                                    condition_matched = true;                               
                                }
                                else
                                {
                                    currue_tag_trigger = true;
                                }
                            }  
                            else
                            {
                                condition_matched = false;
                            }  
                        }
                    }
                }
                break;
            case AUTOMATIC_MODE_FOLLOW:
                {
                    bool result = true;
                    size_t k = 0;
                    for (k = 0; k < automatic_info->conditionInfo[i]->condition_or_info[j]->conditionAnd_index; k++)
                    {
                        tag = automatic_info->conditionInfo[i]->condition_or_info[j]->condition_and_info[k]->tag;
                        if (tag)
                        {
                            if (strcmp(tag->name, tag_this->name) == 0) // 如果是同一个tag，就使用备份,解决写tag是一个备份的问题(传入的tag_this是指向一个备份，里面有最新的写数据)
                            {
                                tag = tag_this;
                            }
                            tag_value_t tag_value = {0};
                            int ret = read_data_form_tag_by_p(tag,TYPE_TAG_INT,&tag_value,automatic_info->conditionInfo[i]->condition_or_info[j]->condition_and_info[k]->value/100);
                            if (ret != 0)
                            {
                                result = false;
                            }
                            else
                            {
                                condition_matched = true;  
                                mode_actVal_value = tag_value.value.to_int;
                            }
                            
                            ems_syslog(LOG_INFO, "get [%s] result %d ", tag->dev_tag_name, result);
                        }
                        else
                        {
                            ems_syslog(LOG_ERR, "tag is NULL!");
                        }                        
                    }

                    if (k > 0)
                    {
                        if (result)
                        {
                            if(trigger_tag)
                            {
                                mode_actVal_value = automatic_info->conditionInfo[i]->actVal;
                                condition_matched = true;                               
                            }
                        }  
                        else
                        {
                            condition_matched = false;
                        }  
                    }
                }
                break;

            default:
                break;
            }
        }
        
    }
    if (condition_matched)
    {
        *distvalue = mode_actVal_value;
        ems_syslog(LOG_INFO, "mode_actVal_value:%d dist:%d ",mode_actVal_value, *distvalue);
        return true;
    }
    else
    {
        if(currue_tag_trigger)
            return false;
        if (automatic_info->reset)
        {
            *distvalue = automatic_info->restValue;
            ems_syslog(LOG_INFO, "resetv:%d dist:%d ",automatic_info->restValue, *distvalue);
            return true;
        }
    }
    
    return false;
}


void automatic_cb(void *context,tag_t *tag)
{
    CONDITION_AND_INFO *condition = context;
    AUTOMATIC_INFO *automatic_Info = (AUTOMATIC_INFO *)condition->up_pr;
    int value;

    if(!checkConditionList(automatic_Info,&value,tag))
    {
        ems_syslog(LOG_ERR, "checkConditionList [%s] [%d] ", condition->name, value);
        return;
    }
    ems_syslog(LOG_INFO, "checkConditionList [%s] [%d] ", condition->name, value);
    if (automatic_Info->tag!=NULL)
    {
        ems_syslog(LOG_NOTICE, "%s strigger check %s  ->%d ", condition->tag->dev_tag_name,automatic_Info->tag->dev_tag_name,value);
        tag_value_t tag_val={.type=TYPE_TAG_INT,.value.to_int=value};
        write_data_to_tag_by_p(automatic_Info->tag,&tag_val,1);
    }
    else //组件处理
    {
        //暂时只有脱扣
        if (value >= 1)
        {
            if (strcmp(automatic_Info->name, "STRIP") == 0)
            {
                ems_syslog(LOG_NOTICE, "no find tag!");
                do_trip();
            }
            else
            {
                char *dot = strstr(automatic_Info->name, ".");
                if ((dot != NULL) && (strcmp(dot + 1, "STRIP") == 0))
                {
                        void vlc_do_trip(void *par); // 为了避开头文件包含问题
                        vlc_do_trip(automatic_Info->name);
                }
            }
        }
    }
    
}


AUTOMATIC_INFO * automatic_init(const char *cfg_f)
{
    proto_forward_t *proto_var = get_proto_forward_var();
    char *f_data = read_file_data(cfg_f);
    if (f_data == NULL)
    {
        ems_syslog(LOG_ERR, "load device config file error, file:%s", cfg_f);
        ems_syslog(LOG_CRIT, "[动环]读取动环文件[%s]失败，确认文件是否存在",cfg_f);
        return NULL;
    }

    cJSON *root = json_parse_string_with_comments(f_data);
    if (!root)
    {
        ems_syslog(LOG_ERR, "parse file to json obj error, file:%s", cfg_f);
        ems_syslog(LOG_CRIT, "[动环]读取动环文件[%s]失败，确认文件格式是否正确",cfg_f);
        goto exit;
    }
    int all_rull_num = cJSON_GetArraySize(root);
    auto_matic_info = calloc(sizeof(AUTOMATIC_INFO),all_rull_num);
#ifdef EN_EMS
    int alarm_20017_reason_code = 1;
    int alarm_20018_reason_code = 1;
    int alarm_20019_reason_code = 1;
#endif
    for (int i = 0; i < all_rull_num; i++)
    {
        
        int register_io_alarm = 0;
        int register_user_alarm = 0;
        int register_user_notice_alarm = 0;
        int register_user_vital_alarm = 0;
        int register_user_server_alarm = 0;
        cJSON *rull = cJSON_GetArrayItem(root, i);
        ems_syslog(LOG_INFO, "--------------------------");
        char name_tmp[256] = {0};
        GET_JSON_VALUE_STRING(rull, "name",name_tmp);
        auto_matic_info[rull_index].tag = find_tag_by_name(proto_var,name_tmp);
        if (auto_matic_info[rull_index].tag==NULL)//组件
        {
            ems_syslog(LOG_ERR, "no finded tag %s",auto_matic_info[rull_index].name);
            if (strstr(name_tmp,"STRIP") != NULL)
            {
                ems_syslog(LOG_ERR, "get STRIP");
            }
            else
            {
                ems_syslog(LOG_CRIT, "[动环]无法获取到 执行动作的tag:[%s]，确认tag是否正确",auto_matic_info[rull_index].name);
                continue;
            }
        }
        else
            ems_syslog(LOG_INFO, "dev_tag_name:%s",auto_matic_info[rull_index].tag->dev_tag_name);

        auto_matic_info[rull_index].name = strdup(name_tmp);
        GET_JSON_VALUE_INT(rull, "reset", auto_matic_info[rull_index].reset);
        GET_JSON_VALUE_INT(rull, "resetValue", auto_matic_info[rull_index].restValue);

        if (strcmp(auto_matic_info[rull_index].name,"EMS." IO_PROTECT) == 0)
        {
            register_io_alarm = 1;
        }
        else if(strcmp(auto_matic_info[rull_index].name,"EMS." USER_ALARM) == 0)
        {
            register_user_alarm = 1;
        }
        else if(strcmp(auto_matic_info[rull_index].name,"EMS." USER_NOTICE_ALARM) == 0)
        {
            register_user_notice_alarm = 1;
        }
        else if(strcmp(auto_matic_info[rull_index].name,"EMS." USER_VITAL_ALARM) == 0)
        {
            register_user_vital_alarm = 1;
        }
        else if(strcmp(auto_matic_info[rull_index].name,"EMS." USER_SERVER_ALARM) == 0)
        {
            register_user_server_alarm = 1;
        }

        // 先遍历一遍，检查是否有条件配置了debounceTime
        auto_matic_info[rull_index].delaystriggered = false;
        cJSON *conditionInfo_pre = cJSON_GetObjectItemCaseSensitive(rull, "conditionInfo");
        if (conditionInfo_pre != NULL) 
        {
            int conditionInfoSize_pre = cJSON_GetArraySize(conditionInfo_pre);
            for (int j_pre = 0; j_pre < conditionInfoSize_pre; j_pre++) 
            {
                cJSON *condition_pre = cJSON_GetArrayItem(conditionInfo_pre, j_pre);
                cJSON *conditionList_pre = cJSON_GetObjectItemCaseSensitive(condition_pre, "conditionList");
                if (conditionList_pre != NULL) 
                {
                    int conditionListSize_pre = cJSON_GetArraySize(conditionList_pre);
                    for (size_t k_pre = 0; k_pre < conditionListSize_pre; k_pre++) 
                    {
                        cJSON *conditionOrInfo_pre = cJSON_GetArrayItem(conditionList_pre, k_pre);
                        cJSON *andList_pre = cJSON_GetObjectItemCaseSensitive(conditionOrInfo_pre, "and_list");
                        if (andList_pre != NULL) 
                        {
                            int conditionAndSize_pre = cJSON_GetArraySize(andList_pre);
                            for (size_t l_pre = 0; l_pre < conditionAndSize_pre; l_pre++) 
                            {
                                cJSON *conditionAndInfo_pre = cJSON_GetArrayItem(andList_pre, l_pre);
                                int debounceTime_pre = 0;
                                GET_JSON_VALUE_INT(conditionAndInfo_pre, "debounceTime", debounceTime_pre);
                                if (debounceTime_pre > 0) 
                                {
                                    auto_matic_info[rull_index].delaystriggered = true;
                                    ems_syslog(LOG_INFO, "Rule %s has debounceTime configured, will use delay task", name_tmp);
                                    break;
                                }
                            }
                            if (auto_matic_info[rull_index].delaystriggered) 
                            {
                                break;
                            }
                        }
                    }
                    if (auto_matic_info[rull_index].delaystriggered) 
                    {
                        break;
                    }
                }
            }
        }
        
        cJSON *conditionInfo = cJSON_GetObjectItemCaseSensitive(rull, "conditionInfo");
        if (conditionInfo == NULL)
        {
            ems_syslog(LOG_ERR, "conditionInfo is NULL");
        }
        int conditionInfoSize = cJSON_GetArraySize(conditionInfo);
        auto_matic_info[rull_index].conditionInfo = calloc(conditionInfoSize+1,sizeof(void *));
        int condition_index = 0;
        for (int j = 0; j < conditionInfoSize; j++)
        {
            cJSON *condition = cJSON_GetArrayItem(conditionInfo, j);
            auto_matic_info[rull_index].conditionInfo[condition_index] = calloc(1,sizeof(CONDITION_INFO));
            GET_JSON_VALUE_INT(condition, "actVal", auto_matic_info[rull_index].conditionInfo[condition_index]->actVal);
            cJSON *conditionList = cJSON_GetObjectItemCaseSensitive(condition, "conditionList");
            int conditionListSize = cJSON_GetArraySize(conditionList);
            auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info = calloc(conditionListSize+1,sizeof(void *));
            int conditionList_index = 0;
            for (size_t k = 0; k < conditionListSize; k++)
            {                
                cJSON *conditionOrInfo = cJSON_GetArrayItem(conditionList, k);
                auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index] = calloc(1,sizeof(CONDITION_OR_INFO));
                GET_JSON_VALUE_INT(conditionOrInfo, "mode", auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->mode);
                cJSON *andList = cJSON_GetObjectItemCaseSensitive(conditionOrInfo, "and_list");
                int conditionAndSize = cJSON_GetArraySize(andList);
                auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info = calloc(conditionAndSize+1,sizeof(void *));
                ems_syslog(LOG_INFO, "conditionAndSize %d",conditionAndSize);
                
                alarm_condition_list register_alarm_param_t = {0};
                int conditionAnd_index = 0;
                for (size_t l = 0; l < conditionAndSize; l++)
                {
                    cJSON *conditionAndInfo = cJSON_GetArrayItem(andList, l);
                    auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index] = calloc(1,sizeof(CONDITION_AND_INFO));
                    GET_JSON_VALUE_DY_STRING(conditionAndInfo, "name", auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->name);
                    auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->tag = find_tag_by_name(proto_var,auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->name); 
                    if (auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->tag!=NULL) //直接注册回调
                    {
                        if(auto_matic_info[rull_index].delaystriggered == true)
                        {
                            ems_syslog(LOG_INFO, "tag has debounceTime configured, will use delay task");
                        }
                        else
                        {
                            if ((auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->mode == AUTOMATIC_MODE_REPEAT)||(auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->mode == AUTOMATIC_MODE_STOP))
                                register_data_flush_cb_by_tag(proto_var,auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->tag,automatic_cb,auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]);
                            else
                                register_data_collect_cb_by_tag(proto_var,auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->tag,automatic_cb,auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]);                       
                        }
                        ems_syslog(LOG_INFO, "condition name:%s",auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->tag->dev_tag_name);
                    }
                    else //加载组件 做组件的话下面的continue要去掉 写入组件相关
                    {
                        ems_syslog(LOG_ERR, "no finded tag %s",auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->name);
                        conditionAnd_index = 0; //这里可能会导致一定程度内存泄漏 但是是一次性的不影响
                        ems_syslog(LOG_CRIT, "[动环]无法获取到 判断条件tag:[%s]，确认tag是否正确",auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->name);
                        break;
                        // continue;
                        // exit(0);//暂时先退出 如果有不能用的tag 方便查找配置出错的地方
                    }
                    
                    cJSON *tmp_cjson = cJSON_GetObjectItemCaseSensitive(conditionAndInfo, "condition");
                    // GET_JSON_VALUE_STRING(conditionAndInfo, "condition",tmp_char);  
                    auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->condition = get_condition_by_string(tmp_cjson->valuestring);
                    cJSON *value_item = cJSON_GetObjectItemCaseSensitive(conditionAndInfo, "value");
                    if (value_item) 
                    {
                        if (value_item->type == cJSON_String) 
                        {
                            GET_JSON_VALUE_DY_STRING(conditionAndInfo, "value", auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->value_tag_name);                   
                            auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->value_is_tag = find_tag_by_name(proto_var, auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->value_tag_name);                           
                        } 
                        else if (value_item->type == cJSON_Number) 
                        {
                            auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->value = value_item->valueint;
                        }
                    }
                    // GET_JSON_VALUE_INT(conditionAndInfo, "value", auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->value);
                    GET_JSON_VALUE_INT(conditionAndInfo, "debounceTime", auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->debounceTime);
                    if (auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->debounceTime < 0) 
                    {
                        auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->debounceTime = 0;
                    }                    
                    if (((register_io_alarm == 1) || (register_user_alarm == 1) || (register_user_notice_alarm == 1) || (register_user_vital_alarm == 1) || (register_user_server_alarm == 1)) && (register_alarm_param_t.num < ALARM_CHILD_CONDS_NUM_MAX))
                    {
                        register_alarm_param_t.register_alarm_param_info[register_alarm_param_t.num].condition = auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->condition;
                        register_alarm_param_t.register_alarm_param_info[register_alarm_param_t.num].tag = auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->tag;
                        register_alarm_param_t.register_alarm_param_info[register_alarm_param_t.num++].value = auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->value;
                    }
                    auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->up_pr = &auto_matic_info[rull_index];
                    ems_syslog(LOG_INFO, "name:%s,condition:%d,value:%d",auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->name,\
                    auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->condition,\
                    auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->condition_and_info[conditionAnd_index]->value);
                    conditionAnd_index++;
                }
#ifdef EN_EMS
                if (register_alarm_param_t.num > 0 && register_io_alarm == 1)
                {
                    register_ems_io_protect_alarm(&register_alarm_param_t);
                }
                if (register_alarm_param_t.num > 0 && register_user_alarm == 1)
                {
                     register_ems_device_alarm(&register_alarm_param_t);
                }
                if (register_alarm_param_t.num > 0 && register_user_notice_alarm == 1)
                {
                    register_ems_user_define_alarm(&register_alarm_param_t, 20017, alarm_20017_reason_code++);
                }

                if (register_alarm_param_t.num > 0 && register_user_vital_alarm == 1)
                {
                    register_ems_user_define_alarm(&register_alarm_param_t, 20018, alarm_20018_reason_code++);
                }

                if (register_alarm_param_t.num > 0 && register_user_server_alarm == 1)
                {
                    register_ems_user_define_alarm(&register_alarm_param_t, 20019, alarm_20019_reason_code++);
                }
#endif
                auto_matic_info[rull_index].conditionInfo[condition_index]->condition_or_info[conditionList_index]->conditionAnd_index = conditionAnd_index;
                if (conditionAnd_index>0)
                {
                    conditionList_index++;
                }
            }
            auto_matic_info[rull_index].conditionInfo[condition_index]->conditionList_index = conditionList_index;
            if (conditionList_index>0)
            {
                condition_index++;
            }
        }
        ems_syslog(LOG_INFO, "--------------------------");
        auto_matic_info[rull_index].condition_index = condition_index;
        if (condition_index>0)
        {
            rull_index++;
        }
    }
    do_automatic_delay_work();
    cJSON_Delete(root);
exit:

    free(f_data);
    return auto_matic_info;
}

void *automatic_delay_task(void *args)
{
    while(1)
    {
        tag_t *tag;
        if(rull_index)
        {
            for(int i = 0; i < rull_index; i++)
            {
                if(auto_matic_info[i].delaystriggered == true)
                {
                    for(int j = 0; j < auto_matic_info[i].condition_index; j++)
                    {
                        for(int k = 0; k < auto_matic_info[i].conditionInfo[j]->conditionList_index; k++)
                        {
                            for(int l = 0; l < auto_matic_info[i].conditionInfo[j]->condition_or_info[k]->conditionAnd_index; l++)
                            {
                                int value = 0;
                                tag = auto_matic_info[i].conditionInfo[j]->condition_or_info[k]->condition_and_info[l]->tag;
                                if(tag)
                                {
                                    if(checkConditionList(&auto_matic_info[i], &value, tag))
                                    {
                                        ems_syslog(LOG_INFO, "checkConditionList [%s] [%d] ", auto_matic_info[i].name, value);
                                        if (auto_matic_info[i].tag!=NULL)
                                        {
                                            ems_syslog(LOG_NOTICE, "delay task %s strigger check %s  ->%d ", auto_matic_info[i].name, auto_matic_info[i].tag->dev_tag_name,value);
                                            tag_value_t tag_val={.type=TYPE_TAG_INT,.value.to_int=value};
                                            write_data_to_tag_by_p(auto_matic_info[i].tag,&tag_val,1);
                                        }
                                        else //组件处理
                                        {
                                            //暂时只有脱扣
                                            if (value >= 1)
                                            {
                                                if (strcmp(auto_matic_info[i].name, "STRIP") == 0)
                                                {
                                                    ems_syslog(LOG_NOTICE, "no find tag!");
                                                    do_trip();
                                                }
                                                else
                                                {
                                                    char *dot = strstr(auto_matic_info[i].name, ".");
                                                    if ((dot != NULL) && (strcmp(dot + 1, "STRIP") == 0))
                                                    {
                                                        void vlc_do_trip(void *par); // 为了避开头文件包含问题
                                                        vlc_do_trip(auto_matic_info[i].name);
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }                         
                            }
                        }
                    }
                }
            }
        }
        sleep(1);
    }
    return NULL;
}
void do_automatic_delay_work(void)
{
    pthread_t tip;
    if (0 == pthread_create(&tip, NULL, automatic_delay_task, NULL))
    {
        pthread_setname_np(tip, "automatic delay task");
    }
}