package com.zcxk.util;

import java.util.HashMap;
import java.util.Map;

public class Parser {
    /**
     * 将字符串text中由openToken和closeToken组成的占位符依次替换为args数组中的值
     * @param openToken
     * @param closeToken
     * @param text
     * @param args
     * @return
     */
    public static String parse(String openToken, String closeToken, String text, Object... args) {
        if (args == null || args.length <= 0) {
            return text;
        }
        int argsIndex = 0;
        if (text == null || text.isEmpty()) {
            return "";
        }
        char[] src = text.toCharArray();
        int offset = 0;
        // search open token
        int start = text.indexOf(openToken, offset);
        if (start == -1) {
            return text;
        }
        final StringBuilder builder = new StringBuilder();
        StringBuilder expression = null;
        while (start > -1) {
            if (start > 0 && src[start - 1] == '\\') {
                // this open token is escaped. remove the backslash and continue.
                builder.append(src, offset, start - offset - 1).append(openToken);
                offset = start + openToken.length();
            } else {
                // found open token. let's search close token.
                if (expression == null) {
                    expression = new StringBuilder();
                } else {
                    expression.setLength(0);
                }
                builder.append(src, offset, start - offset);
                offset = start + openToken.length();
                int end = text.indexOf(closeToken, offset);
                while (end > -1) {
                    if (end > offset && src[end - 1] == '\\') {
                        // this close token is escaped. remove the backslash and continue.
                        expression.append(src, offset, end - offset - 1).append(closeToken);
                        offset = end + closeToken.length();
                        end = text.indexOf(closeToken, offset);
                    } else {
                        expression.append(src, offset, end - offset);
                        offset = end + closeToken.length();
                        break;
                    }
                }
                if (end == -1) {
                    // close token was not found.
                    builder.append(src, start, src.length - start);
                    offset = src.length;
                } else {
                    ///////////////////////////////////////仅仅修改了该else分支下的个别行代码////////////////////////
                    String value = (argsIndex <= args.length - 1) ?
                            (args[argsIndex] == null ? "" : args[argsIndex].toString()) : expression.toString();
                    builder.append(value);
                    offset = end + closeToken.length();
                    argsIndex++;
                    ////////////////////////////////////////////////////////////////////////////////////////////////
                }
            }
            start = text.indexOf(openToken, offset);
        }
        if (offset < src.length) {
            builder.append(src, offset, src.length - offset);
        }
        return builder.toString();
    }
    public static String parse(String text, Object... args) {
        return Parser.parse("${", "}", text, args);
    }

    /**
     * 只替换第一个{key}中的内容，{}中内容首尾的空白字符去除之后作为key
     * 但是key中的空白字符不做处理
     * 即使第一个{key}替换失败，后面的{key}也不做处理
     * @param source
     * @param params
     * @return
     */
    public static String replaceFirst(String source, Map<String, String> params) {
        int begin = source.indexOf("{");
        int end = source.indexOf("}");
        //source存在"{"，并且"{"的位置在"}"之前时进行替换
        if((begin > -1) && (begin < end)) {
            //取出{key}中的可以并去除首尾的空白字符
            String sub = source.substring(begin + 1, end);
            sub = sub.trim();	//去除首尾空白字符
            //System.out.println(sub);
            if(params.containsKey(sub)) {
                //连同{和}一起进行替换
                String regex = source.substring(begin, end + 1);
                source = source.replace(regex, params.get(sub));
            }
        }
        return source;
    }

    /**
     * 对字符串中的所有{key}进行替换，但是key中含有的空白字符不做处理
     * @param source
     * @param params
     * @return
     */
    public static String replaceAll(String source, Map<String, String> params) {
        int begin = source.indexOf("{");
        int end = 0;
        String sub = "";
        while(begin > -1) {
            //end = source.indexOf("}");	//如果用此方式可能造成死循环
            //并不能保证每个{key}都会被替换掉，所以需要从上次的{之后进行匹配
            end = source.indexOf("}", begin);
            if(begin < end) {
                sub = source.substring(begin + 1, end);
                //sub = sub.replaceAll("\\s*", "");	//去除所有空白字符
                sub = sub.trim();	//去除首尾空白字符
                if(params.containsKey(sub)) {
                    String regex = source.substring(begin, end + 1);
                    source = source.replace(regex, params.get(sub));
                }
                begin = source.indexOf("{", begin+1);	//如此取值方为合理
            }
            //begin = source.indexOf("{");	//如果用此方式可能造成死循环
        }
        return source;
    }

    /**
     * 对字符串中的所有{key}进行替换，并且会清除key中包含的空白字符之后再进行匹配
     * @param source
     * @param params
     * @return
     */
    public static String replaceAllClearBlanks(String source, Map<String, String> params) {
        int begin = source.indexOf("${");
        int end = 0;
        String sub = "";
        while(begin > -1) {
            //end = source.indexOf("}");	//如果用此方式可能造成死循环
            //并不能保证每个{key}都会被替换掉，所以需要从上次的{之后进行匹配
            end = source.indexOf("}", begin);
            if(begin < end) {
                sub = source.substring(begin + 2, end);
                sub = sub.replaceAll("\\$\\s*\\d*", "");	//去除所有空白字符
                //sub = sub.trim();	//去除首尾空白字符
                if(params.containsKey(sub)) {
                    String regex = source.substring(begin, end + 1);
                    source = source.replace(regex, params.get(sub));
                }
                begin = source.indexOf("${", begin+2);	//如此取值方为合理
            }
            //begin = source.indexOf("{");	//如果用此方式可能造成死循环
        }
        return source;
    }


    public static void main(String... args) {
        String test="${场景名称} ${设备名称} ${状态}${报警规则}";
        Map<String,String>replace=new HashMap<>();
        replace.put("场景名称","money");
        replace.put("设备名称","flower");
        replace.put("状态","01");
        replace.put("报警规则","777");
        String s = replaceAllClearBlanks(test, replace);
        System.out.println(s);
    }
}
