package com.xunmei.common.core.util;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.*;

/**
 * Tkk
 */
public class BeanHelper {

    /**
     * 主要过滤 null 值
     *
     * @param target
     * @param source
     */
    public static void copyProperties(Object target, Object source) {
        BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
    }

    /**
     * 主要过滤 null 值
     *
     * @param oldValue
     * @param newValue
     */
    public static void copyProperties(Object oldValue, Object newValue, String... exclude) {
        BeanUtils.copyProperties(newValue, oldValue, getNullPropertyNames(newValue, exclude));
    }

    /**
     * 忽略为null的数据
     *
     * @param source
     * @return
     */
    public static String[] getNullPropertyNames(Object source, String... ignores) {
        BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(source);
        PropertyDescriptor[] pds = beanWrapper.getPropertyDescriptors();
        List<String> ignoreList = new LinkedList<>();
        for (PropertyDescriptor pd : pds) {
            if (pd.getWriteMethod() == null) {
                continue;
            }
            Object srcValue = beanWrapper.getPropertyValue(pd.getName());
            if (srcValue == null) {
                ignoreList.add(pd.getName());
            }
        }
        String[] result = ignoreList.toArray(new String[ignoreList.size()]);
        return ignores == null ? result : ArrayUtils.addAll(result, ignores);
    }


    public static void setNullPropertiesDefValue(Object obj) {
        //获取实体类的所有属性，返回Field数组
        // Field[] fields = obj.getClass().getDeclaredFields();
        Field[] fields = getAllFields(obj.getClass());
        //遍历所有属性
        for (int j = 0; j < fields.length; j++) {
            Field field = fields[j];
            String type = field.getGenericType().toString();
            field.setAccessible(true);
            Object value = null;
            try {
                value = field.get(obj);
                if (value != null && StringUtils.isNotBlank(value.toString())) {
                    continue;
                }
                //如果type是类类型，则前面包含"class "，后面跟类名
                switch (type) {
                    case "class java.lang.String":
                        field.set(obj, StringUtils.EMPTY);
                        break;
                    case "class java.math.BigDecimal":
                        field.set(obj, BigDecimal.ZERO);
                        break;
                    case "class java.util.Date":
                        field.set(obj, new Date());
                        break;
                    case "class java.lang.Integer":
                        field.set(obj, 0);
                        break;
                    case "class java.lang.Character":
                        field.set(obj, '0');
                        break;
                    case "class java.lang.Short":
                        field.set(obj, Short.valueOf((short) 0));
                        break;
                    case "class java.lang.Byte":
                        field.set(obj, Byte.valueOf((byte) 0));
                        break;
                    case "class java.lang.Double":
                        field.set(obj, 0D);
                        break;
                    case "class java.lang.Float":
                        field.set(obj, 0F);
                        break;
                    case "class java.lang.Long":
                        field.set(obj, 0L);
                        break;
                    case "class java.lang.Boolean":
                        field.set(obj, false);
                        break;
                    default:
                        break;
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 获取本类及其父类的属性的方法
     *
     * @param clazz 当前类对象
     * @return 字段数组
     */
    private static Field[] getAllFields(Class<?> clazz) {
        List<Field> fieldList = new ArrayList<>();
        while (clazz != null) {
            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
            clazz = clazz.getSuperclass();
        }
        Field[] fields = new Field[fieldList.size()];
        return fieldList.toArray(fields);
    }
}
