package com.common.service;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.common.mapper.SyslogNormalDataMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;

@Slf4j
@Service
@RequiredArgsConstructor
public class LogDataFilterService {

    /**
     * 评估过滤规则
     */
    public boolean evaluateFilterRule(String ruleContent, Map<String, Object> destMap) {
        try {
            JSONObject ruleJson = JSON.parseObject(ruleContent);
            if (ruleJson.containsKey("filters_params")  ) {
                JSONObject filtersParamsObj = ruleJson.getJSONObject("filters_params");
                JSONArray filtersParams = filtersParamsObj.getJSONArray("expressions");

                if (filtersParams == null || filtersParams.isEmpty()) {
                    log.warn("泛化规则-数据过滤规则为空，默认不处理!");
                    return false;
                }
                // 遍历所有过滤组，只要满足任一过滤组即可
                for (int i = 0; i < filtersParams.size(); i++) {
                    JSONObject filterGroup = filtersParams.getJSONObject(i);
                    if (evaluateFilterGroup(filterGroup, destMap)) {
                        return true;
                    }
                }
            }
            return false;

        } catch (Exception e) {
            log.error("解析过滤规则失败或filters_params为空: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 评估过滤组
     */
    private boolean evaluateFilterGroup(JSONObject filterGroup, Map<String, Object> destMap) {
        try {
            //JSONObject expressions_obj = filterGroup.getJSONObject("expressions");
            JSONArray expressions = filterGroup.getJSONArray("expressions");
            String relation = filterGroup.getString("filters_relation");

            if (expressions == null || expressions.isEmpty()) {
                return false;
            }

            // 根据关系类型评估
            if ("or".equalsIgnoreCase(relation)) {
                return evaluateOrExpressions(expressions, destMap);
            } else {
                // 默认使用 AND 关系
                return evaluateAndExpressions(expressions, destMap);
            }
        } catch (Exception e) {
            log.error("评估过滤组evaluateFilterGroup解析json失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 评估 AND 关系的表达式
     */
    private boolean evaluateAndExpressions(JSONArray expressions, Map<String, Object> destMap) {
        for (int i = 0; i < expressions.size(); i++) {
            JSONObject expression = expressions.getJSONObject(i);
            if (!evaluateExpression(expression, destMap)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 评估 OR 关系的表达式
     */
    private boolean evaluateOrExpressions(JSONArray expressions, Map<String, Object> destMap) {
        for (int i = 0; i < expressions.size(); i++) {
            JSONObject expression = expressions.getJSONObject(i);
            if (evaluateExpression(expression, destMap)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 评估单个表达式
     */
    private boolean evaluateExpression(JSONObject expression, Map<String, Object> destMap) {
        String columnName = expression.getString("column_name");
        String op = expression.getString("op");
        Object value = expression.get("value");

        // 从目标Map中获取字段值
        Object fieldValue = destMap.get(columnName);
        if (fieldValue == null) {
            fieldValue = ""; // 处理null值
        }

        String fieldValueStr = fieldValue.toString();

        try {
            switch (op) {
                case "=":
                    return equals(fieldValueStr, value);
                case "!=":
                    return notEquals(fieldValueStr, value);
                case "in":
                    return in(fieldValueStr, value);
                case "zero_len":
                    return zeroLen(fieldValueStr, value);
                case "contain":
                    return contain(fieldValueStr, value);
                case "regexp":
                    return regexp(fieldValueStr, value);
                default:
                    log.warn("未知的操作符: {}", op);
                    return false;
            }
        } catch (Exception e) {
            log.error("评估表达式失败: {}{}{}, 错误: {}", columnName, op, value, e.getMessage());
            return false;
        }
    }

    /**
     * 等于操作
     */
    private boolean equals(String fieldValue, Object value) {
        return fieldValue.equals(value.toString());
    }

    /**
     * 不等于操作
     */
    private boolean notEquals(String fieldValue, Object value) {
        return !fieldValue.equals(value.toString());
    }

    /**
     * IN 操作
     */
    private boolean in(String fieldValue, Object value) {
        if (value instanceof JSONArray) {
            JSONArray array = (JSONArray) value;
            for (Object item : array) {
                if (fieldValue.equals(item.toString())) {
                    return true;
                }
            }
            return false;
        }
        return false;
    }

    /**
     * 长度检查操作
     */
    private boolean zeroLen(String fieldValue, Object value) {
        boolean isEmpty = !StringUtils.hasText(fieldValue);
        boolean expected = Boolean.parseBoolean(value.toString());
        return isEmpty == expected;
    }

    /**
     * 包含操作
     */
    private boolean contain(String fieldValue, Object value) {
        return fieldValue.contains(value.toString());
    }

    /**
     * 正则表达式匹配
     */
    private boolean regexp(String fieldValue, Object value) {
        try {
            Pattern pattern = Pattern.compile(value.toString());
            return pattern.matcher(fieldValue).matches();
        } catch (Exception e) {
            log.error("正则表达式编译失败: {}, 错误: {}", value, e.getMessage());
            return false;
        }
    }


}