package net.northking.cctp.se.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
public class RegexUtils {
    private final static String GLOBAL_VAR_REGEX = "#\\{([^}]*)\\}";
    private final static String SCRIPT_VAR_REGEX = "\\$\\{([^}]*)\\}";
    private final static String FUZZY_VAR_REGEX = "%\\{([^}]*)}";
    private final static Pattern GLOBAL_VAR_PATTERN  = Pattern.compile(GLOBAL_VAR_REGEX);
    private final static Pattern SCRIPT_VAR_PATTERN = Pattern.compile(SCRIPT_VAR_REGEX);
    private final static Pattern FUZZY_VAR_PATTERN = Pattern.compile(FUZZY_VAR_REGEX);

    private RegexUtils(){}

    public static boolean containGlobalVar(String str){
        return GLOBAL_VAR_PATTERN.matcher(str).find();
    }
    public static Set<String> extractGlobalVar(String str){
        Set<String> ret = new HashSet<>();
        Matcher matcher = GLOBAL_VAR_PATTERN.matcher(str);
        while(matcher.find()){
            String group = matcher.group();
            String var = group.substring(2,group.length()-1);
            ret.add(var);
            log.debug("find global var expr,expr:{},var:{}",group,var);
        }
        return  ret;
    }
    public static boolean containScriptVar(String str){
        return SCRIPT_VAR_PATTERN.matcher(str).find();
    }
    public static Set<String> extractScriptVar(String str){
        Set<String> ret = new HashSet<>();
        Matcher matcher = SCRIPT_VAR_PATTERN.matcher(str);
        while(matcher.find()){
            String group = matcher.group();
            String var = group.substring(2,group.length()-1);
            ret.add(var);
            log.debug("find script var expr,expr:{},var:{}",group,var);
        }
        return  ret;
    }
    public static boolean containFuzzyVar(String str){
        return FUZZY_VAR_PATTERN.matcher(str).find();
    }
    public static List<String> extractFuzzyVar(String str){
        List<String> ret = new ArrayList<>();
        Matcher matcher = FUZZY_VAR_PATTERN.matcher(str);
        while(matcher.find()){
            String group = matcher.group();
            String var = group.substring(2,group.length()-1);
            ret.add(var);
            log.debug("find fuzzy var expr,expr:{},var:{}",group,var);
        }
        return  ret;
    }

    public static String replace(String expression, String varName, String value, VarType varType) {
        if (StringUtils.isBlank(expression) || StringUtils.isBlank(varName) || null == varType) {
            return expression;
        }
        switch (varType) {
            case GLOBAL:
                if (containGlobalVar(expression)) {
                    String with = "#{" + varName + "}";
                    expression = expression.replace(with, value);
                }
                break;
            case SCRIPT:
                if (containScriptVar(expression)) {
                    String with = "${" + varName + "}";
                    expression = expression.replace(with, value);
                }
                break;
            case FUZZY:
                if (containFuzzyVar(expression)) {
                    String with = "%\\{" + varName + "}";
                    expression = expression.replaceFirst(with, value);
                }
                break;
        }
        return expression;
    }

    public enum VarType {
        GLOBAL, SCRIPT, FUZZY
    }


}
