package cn.stylefeng.workflow.rule.sdk;

import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.roses.kernel.rule.pojo.response.ErrorResponseData;
import cn.stylefeng.roses.kernel.rule.pojo.response.ResponseData;
import cn.stylefeng.roses.kernel.rule.pojo.response.SuccessResponseData;
import cn.stylefeng.workflow.rule.api.ExpressionEngineApi;
import cn.stylefeng.workflow.rule.sdk.util.SpringFunctions;
import lombok.extern.slf4j.Slf4j;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.util.Map;

@Component
@Slf4j
public class SpringExpressionEngine implements ExpressionEngineApi {

    private final ExpressionParser SPRING_EL_EXPRESSION_PARSER = new SpelExpressionParser();

    @Override
    public boolean parseExpression(String expression) {
        return Boolean.TRUE.equals(SPRING_EL_EXPRESSION_PARSER.parseExpression(expression).getValue(Boolean.class));
    }

    @Override
    public boolean parseExpression(String expressionStr, Map<String, Object> variables) {
        StandardEvaluationContext context = new StandardEvaluationContext();
        try {
            context.registerFunction("isBlank", SpringFunctions.class.getDeclaredMethod("isBlank", String.class));
        } catch (NoSuchMethodException e) {
            log.error("Spring EL解析错误，找不到指定方法", e);
            return false;
        }
        try {
            if (ObjectUtil.isNotEmpty(variables)) {
                context.setVariables(variables);
            }
            Expression expression = SPRING_EL_EXPRESSION_PARSER.parseExpression(expressionStr);
            return Boolean.TRUE.equals(expression.getValue(context, Boolean.class));
        } catch (Exception e) {
            log.error("Spring EL表达式解析错误", e);
            return false;
        }
    }

    @Override
    public ResponseData<?> validateExpression(String expressionStr) {
        ExpressionParser parser = new SpelExpressionParser();
        try {
            parser.parseExpression(expressionStr);
            return new SuccessResponseData<>();
        } catch (Exception e) {
            return new ErrorResponseData<>("500", "表达式校验错误：" + e.getMessage());
        }
    }

}
