package cn.ey.biz.module.system.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author Jian.Yang
 */
public class MapKeyConvert {

    private static final Pattern HUMP_PATTERN = Pattern.compile("[A-Z]");
    private static final Pattern LINE_PATTERN = Pattern.compile("_[a-z]");

    private volatile static Map<String, String> COLUMN_NAME_PROP_NAME_CACHE_MAP = new HashMap<>(16);

    private MapKeyConvert() {
    }

    /***
     * 将驼峰转为下划线
     *
     * @param str key
     * @return java.lang.String
     **/
    public static String humpToUnderline(String str) {

        if (StrUtil.isEmpty(str)) {
            return null;
        }
        if (str.length() >= Integer.MAX_VALUE) {
            throw new RuntimeException("Enter a valid string");
        }

        Matcher matcher = HUMP_PATTERN.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
        }
        matcher.appendTail(sb);
        return sb.toString();
    }

    /***
     * 将下划线转为驼峰
     *
     * @param str key
     * @return java.lang.String
     **/
    public static String underlineToHump(String str) {
        str = str.toLowerCase();
        Matcher matcher = LINE_PATTERN.matcher(str);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            matcher.appendReplacement(sb, matcher.group(0).toUpperCase().replace("_", ""));
        }
        matcher.appendTail(sb);
        return sb.toString();
    }


    /**
     * 把list map 原生JDBC结果集中，字段名，也就是MAP中的KEY，转换为驼峰规则的JAVA对属性名
     *
     * @param resultList JDBC 结果集
     */
    public static void convertDbColumnName2ObjectPropName(List<Map<String, Object>> resultList) {
        if (CollUtil.isNotEmpty(resultList)) {
            List<Map<String, Object>> convertList = new ArrayList<>(resultList.size());
            //Map<String, String> columnNamePropNameCacheMap = new HashMap<>(16);
            for (Map<String, Object> currMap : resultList) {
                Map<String, Object> tempMap = new HashMap<>(16);
                convertList.add(tempMap);
                for (Map.Entry<String, Object> entry : currMap.entrySet()) {
                    String dbColumnName = entry.getKey();
                    Object value = entry.getValue();
                    if (COLUMN_NAME_PROP_NAME_CACHE_MAP.get(dbColumnName) == null) {
                        String currProName = underlineToHump(dbColumnName);
                        tempMap.put(currProName, value);
                        COLUMN_NAME_PROP_NAME_CACHE_MAP.put(dbColumnName, currProName);
                    } else {
                        tempMap.put(COLUMN_NAME_PROP_NAME_CACHE_MAP.get(dbColumnName), value);
                    }
                }
            }
            resultList.clear();
            resultList.addAll(convertList);
            convertList.clear();
        }
    }

}
