package com.sifang.modules.sys.util;

import com.jfinal.kit.StrKit;
import org.apache.commons.lang3.StringUtils;

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

public class SqlUtils {

    private static final Map<String, Pattern> ESC_TABLE = createMap();

    private static Map<String, Pattern> createMap() {
        Map<String, Pattern> ret = new HashMap<>();
        ret.put("\\\\", literalPatt("\\"));
        ret.put("\\\"", literalPatt("\""));
        ret.put("\\'", literalPatt("'"));
        ret.put("\\0", literalPatt("\0"));
        ret.put("\\n", literalPatt("\n"));
        ret.put("\\b", literalPatt("\b"));
        ret.put("\\r", literalPatt("\r"));
        ret.put("\\t", literalPatt("\t"));
        ret.put("\\%", literalPatt("%"));
        ret.put("\\_", literalPatt("_"));
        ret.put("\\Z", literalPatt("\u001A")); // \Z ctrl+z
        return Collections.unmodifiableMap(ret);
    }

    private static Pattern literalPatt(CharSequence seq) {
        return Pattern.compile(seq.toString(), Pattern.LITERAL);
    }


    public static String inParam(String... params) {
        if (params == null || params.length < 1) {
            throw new IllegalArgumentException("in params requires at least one value");
        }

        return inParam(Arrays.asList(params));
    }

    public static String genInParamSql(Collection col){
        if (col == null || col.size() < 1) {
            throw new IllegalArgumentException("in params requires at least one value");
        }
        Iterator it = col.iterator();
        StringBuilder sb = new StringBuilder("");
        while (it.hasNext()){
            String value = escapeInValue(String.valueOf(it.next()));
            sb.append(",").append("'").append(value).append("'");
        }
        return sb.toString().substring(1);
    }

    public static String inParam(List<String> params) {
        return genInParamSql(params);
    }

    private static String escapeInValue(String value) {
        if (StringUtils.isBlank(value)) {
            throw new IllegalArgumentException("blank is not allowed for sql in-statement");
        }
        return escapeSql(value);
    }

    public static String escapeSql(String str) {
        if (str != null && str.length() > 0) {
            for (Map.Entry<String, Pattern> entry : ESC_TABLE.entrySet()) {
                str = entry.getValue().matcher(str).replaceAll(Matcher.quoteReplacement(entry.getKey()));
            }
        }
        return str;
    }

    public static String generateLimitSqlForMysql(Object limit, Object page){
        if(StrKit.notNull(limit, page) && StrKit.notBlank(limit.toString(), page.toString())){
            return " limit " + limit + " offset " + (Integer.valueOf(page.toString()) -1)* Integer.valueOf(limit.toString());
        }
        return "";
    }
}
