package org.matrix.actuators.util;


import com.alibaba.fastjson.JSON;
import com.jayway.jsonpath.Configuration;
import com.jayway.jsonpath.JsonPath;
import org.matrix.actuators.sql.SqlExpActuator;
import org.matrix.util.SpringUtils;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 补全http和检验点中的表达式的一些公共方法
 * @author huangxiahao
 */
@Component
public class CompleteExpressionUtil {

    public static final String JSON_PATH_REG = "\\{(\\s)*\\$.*?}|(<(\\s)*\\$.*?>)";

    public static final String ACTION_REG = "\\$(?=\\{(\\s)*pre\\.)(.*?)(?<=})(\\[(.*?)])?";

    public static final String ENV_VARIABLE_REG = "\\#\\{(.*?)}";

    public static final String DYNAMIC_VARIABLE_REG = "\\$\\{(((?!pre\\.).)*?)}(\\[(.*?)])?";

    public static final String PATH_REG = "\\{(((?!pre\\.).)*?)}(\\[(.*?)])?";

    public String completeDynamicVariable(String expression,Long envId,Long projectId) {
        String result = expression;
        result = regexExpression(
                result, DYNAMIC_VARIABLE_REG,
                null, (o, s) ->
                        getSqlExpActuator().parseVarByName(s,envId,projectId));
        return result;
    }

    public String completePathVariable(String expression, Map<String, String> source) {
        String result = expression;
        result = regexExpression(
                result, PATH_REG,
                source, (o, s) ->
                        ((Map<String, String>)o).get(s));
        return result;
    }

    /**
     *
     * @param expression jsonpath 表达式
     * @param jsonString json字符串
     * @return jsonpath解析结果
     */
    public String completeJsonPathExpression(String expression, String jsonString) {
        Object jsonObject = Configuration.defaultConfiguration().jsonProvider().parse(jsonString);
        return completeJsonPathExpression(expression,jsonObject);
    }

    /**
     *
     * @param jsonObject 这个Object 是由  Configuration.defaultConfiguration().jsonProvider().parse(“json字符串”);  这个方法转换过来的 请不要乱传
     * @return jsonpath解析结果
     */
    public String completeJsonPathExpression(String expression, Object jsonObject) {
        String result = expression;
        result = regexExpression(result, JSON_PATH_REG,
                jsonObject, (o, s) -> JSON.toJSONString(JsonPath.read(o, s.substring(1, s.length() - 1))));
        return result;
    }

    public String regexExpression(String expression, String regex,Object sourceContent, BiFunction<Object,String,String> biFunction){
        String result = expression;
        Pattern pattern = Pattern.compile(regex);
        Matcher mat = pattern.matcher(result);
        StringBuffer sBuffer=new StringBuffer();
        while (mat.find()) {
            String group = mat.group();
            String read = biFunction.apply(sourceContent,group);
            mat.appendReplacement(sBuffer,read);
        }
        mat.appendTail(sBuffer);
        return sBuffer.toString();
    }

    private static SqlExpActuator getSqlExpActuator(){
        return SpringUtils.getBean("sqlExpActuator");
    }

}
