package com.crunii.micro.common.utils;

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.util.StringUtils;

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

public class BeanUtil extends org.springframework.beans.BeanUtils {

    /**
     * 根据传入bean查询为null值的属性
     *
     * @param bean bean
     * @return 为null值的属性数组
     */
    public static String[] getNullProperties(Object bean) {
        final BeanWrapper src = new BeanWrapperImpl(bean);
        PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<>();
        for (PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    /**
     * 根据传入bean查询不为null值的属性
     *
     * @param bean bean
     * @return 不为null值的属性数组
     */
    public static String[] getNotNullProperties(Object bean) {
        final BeanWrapper src = new BeanWrapperImpl(bean);
        PropertyDescriptor[] pds = src.getPropertyDescriptors();

        Set<String> emptyNames = new HashSet<>();
        for (PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue != null) {
                emptyNames.add(pd.getName());
            }
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }

    public static void copyPropertiesIgnoreNull(Object source, Object target) {
        copyProperties(source, target, getNullProperties(source));
    }

    /**
     * 获取当前对象所属类类声明的private/protected变量
     *
     * @param object       对象
     * @param propertyName 变量名
     * @return 变量值
     */
    public static Object getFieldValue(Object object, String propertyName) {
        try {
            if (Objects.isNull(object) || StringUtils.isEmpty(propertyName)) {
                throw new RuntimeException("BeanUtils.getFieldValue中object与propertyName不能为空");
            }
            Field field = object.getClass().getDeclaredField(propertyName);
            field.setAccessible(true);
            return field.get(object);
        } catch (IllegalAccessException | NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 将Object类装载的List对象转为List类
     *
     * @param object 装载List类的对象
     * @param clazz  List泛型类class
     * @param <T>    List泛型类
     * @return List
     */
    public static <T> List<T> castList(Object object, Class<T> clazz) {
        if (object instanceof List<?>) {
            List<T> result = new ArrayList<T>();
            for (Object o : (List<?>) object) {
                result.add(clazz.cast(o));
            }
            return result;
        }
        return null;
    }

}
