package com.elab.core.utils;


import org.springframework.beans.BeanUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;

import java.beans.PropertyDescriptor;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * Bean属性操作工具类
 *
 * @author : liukx
 * @create : 2018/8/10 16:00
 * @email : liukx@elab-plus.com
 */
public class BeanPropertyUtils {

    /**
     * 获取Column注解的对应属性值
     *
     * @param o
     * @return
     */
    public static Map<String, String> getColumnProperty(Object o, Class annotationClass, String annotationName) {
        Map<String, String> annotationProperty = new HashMap<>();
        Class<?> mappedClass = o.getClass();
        PropertyDescriptor[] propertyDescriptors = BeanUtils.getPropertyDescriptors(mappedClass);
        for (PropertyDescriptor pd : propertyDescriptors) {
            if (pd.getWriteMethod() != null) {
                String name = pd.getName().toLowerCase();
                Field declaredField = ReflectionUtils.findField(mappedClass, pd.getName());
                if (declaredField != null && declaredField.getAnnotation(annotationClass) != null) {
                    Annotation annotation = declaredField.getAnnotation(annotationClass);
                    Object defaultValue = AnnotationUtils.getDefaultValue(annotation, annotationName);
                    if (defaultValue != null && !"".equals(defaultValue.toString().trim())) {
                        annotationProperty.put(defaultValue.toString(), pd.getName());
                    }
                } else {
                    annotationProperty.put(name, pd.getName());
                }

                String underscoredName = underscoreName(pd.getName());
                if (!pd.getName().toLowerCase().equals(underscoredName)) {
                    annotationProperty.put(underscoredName, pd.getName());
                }
            }
        }
        return annotationProperty;
    }

    /**
     * Convert a name in camelCase to an underscored name in lower utils.
     * Any upper utils letters are converted to lower utils with a preceding underscore.
     *
     * @param name the string containing original name
     * @return the converted name
     */
    public static String underscoreName(String name) {
        if (!StringUtils.hasLength(name)) {
            return "";
        }
        StringBuilder result = new StringBuilder();
        result.append(name.substring(0, 1).toLowerCase());
        for (int i = 1; i < name.length(); i++) {
            String s = name.substring(i, i + 1);
            String slc = s.toLowerCase();
            if (!s.equals(slc)) {
                result.append("_").append(slc);
            } else {
                result.append(s);
            }
        }
        return result.toString();
    }
}
