package com.jay.monitor.data.server.report.alert.rule.config;

import com.jay.monitor.data.core.enums.MsgTypeEnums;
import com.jay.monitor.data.core.model.serializable.MQDataDTO;
import com.jay.monitor.data.core.model.serializable.SQLMonitorDTO;
import com.jay.monitor.data.core.model.serializable.URLDataDTO;
import com.jay.monitor.data.core.model.serializable.base.CommonDataDTO;
import org.junit.Test;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.SpelNode;
import org.springframework.expression.spel.ast.PropertyOrFieldReference;
import org.springframework.expression.spel.standard.SpelExpression;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Consumer;

public class ExpressionValueConditionTest {
    private ExpressionValueCondition condition = new ExpressionValueCondition();

    @Test
    public void commonTest() {
        String conditionString = "${applicationName == 'elab-markeing-gateway' && status == -1 || requestTime > 5000}";

        CommonDataDTO commonDataDTO = new CommonDataDTO(MsgTypeEnums.MQ);
        commonDataDTO.setStatus(-1);
        commonDataDTO.setApplicationName("elab-markeing-gateway");
        boolean match = condition.match(commonDataDTO, conditionString);
        System.out.println(match);
    }

    @Test
    public void test() {
        Map<String, Object> propSet = new HashMap();
        printClazz(MQDataDTO.class, true, (filed) -> {
            propSet.put(filed.getName(), null);
        });
        printClazz(SQLMonitorDTO.class, true, (filed) -> {
            propSet.put(filed.getName(), null);
        });
        printClazz(URLDataDTO.class, true, (filed) -> {
            propSet.put(filed.getName(), null);
        });
        String conditionString =
            "${applicationName == 'elab-markeing-gateway' && status == -1 || requestTime > 5000}";

        Expression expression = condition.getExpression(conditionString);
        //        SpelExpressionParser PARSER = new SpelExpressionParser();

        int index = 0;
        Map<String, Class> inputMap = new HashMap<>();
        SpelNode ast = ((SpelExpression)expression).getAST();
        checkExpression(ast, inputMap);
        System.out.println(inputMap);
        boolean match = condition.match(propSet, conditionString);
        System.out.println(match);
    }

    private void checkExpression(SpelNode node, Map<String, Class> inputMap) {
        if (node instanceof PropertyOrFieldReference) {
            String name = ((PropertyOrFieldReference)node).getName();
            System.out.println(name);
            inputMap.put(name, null);
        } else {
            try {
                SpelNode leftChild = node.getChild(0);
                checkExpression(leftChild, inputMap);
                SpelNode rightChild = node.getChild(1);
                checkExpression(rightChild, inputMap);
            } catch (Exception e) {
                // 查询不到值了.
            }
        }
    }

    private void printClazz(Class clazz, boolean isFindSuper, Consumer<Field> consumer) {

        if (isFindSuper && clazz.getSuperclass() != null) {
            printClazz(clazz.getSuperclass(), true, consumer);
        }

        Field[] declaredFields = clazz.getDeclaredFields();
        Map<String, String> fieldMap = new LinkedHashMap<>();
        for (int i = 0; i < declaredFields.length; i++) {
            Field declaredField = declaredFields[i];
            String name = declaredField.getName();
            Class<?> type = declaredField.getType();
            fieldMap.put(name, type.getSimpleName());
            consumer.accept(declaredField);
        }

        fieldMap.forEach((K, V) -> {
            System.out.println(clazz.getSimpleName() + "\t" + K + "\t" + V);
        });
    }
}