package com.ycwl.basic.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @date 2022年07月14日 14:12
 * 数据格式转换工具类
 */
public class ObjectConvertUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(ObjectConvertUtils.class);

    /**
     * 浅克隆
     *
     * @param source 原对象
     * @param clazz  目标对象
     * @return T
     * @date 2022/4/6 13:45
     */
    public static <T> T clone(Object source, Class<T> clazz) {
        return clone(source, clazz, true);
    }
    /**
     *
     * @date 2022/7/18 16:36
     * @param source 原对象
     * @param clazz 目标对象
     * @param whetherAssignNull 是否赋值空值:true是 false否
     * @return T
     */
    public static <T> T clone(Object source, Class<T> clazz, Boolean whetherAssignNull) {
        T target;

        if (source == null) {
            return null;
        }

        try {
            target = clazz.newInstance();
            if (whetherAssignNull) {
                BeanUtils.copyProperties(source, target);
            } else {
                BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
            }
            return target;
        } catch (Exception e) {
            LOGGER.error("数据转换异常", e);
            return null;
        }
    }

    /**
     * 对象与对象之间的数据转换
     *
     * @param source 转换的数据对象
     * @param target 需要转换数据的对象
     * @date 2022/7/14 17:24
     */
    public static void clone(Object source, Object target) {
        clone(source, target, true);
    }
    /**
     *
     * @date 2022/7/18 16:39
     * @param source 转换的数据对象
     * @param target 需要转换数据的对象
     * @param whetherAssignNull 是否赋值空值:true是 false否
     */
    public static void clone(Object source, Object target, Boolean whetherAssignNull) {
        if (source == null) {
            return;
        }

        try {
            if (whetherAssignNull) {
                BeanUtils.copyProperties(source, target, getNullPropertyNames(source));
            } else {
                BeanUtils.copyProperties(source, target);
            }
        } catch (Exception e) {
            LOGGER.error("数据转换异常", e);
        }
    }

    /**
     * 对象与对象之间的数据转换
     *
     * @param source 转换的数据对象
     * @param target 需要转换数据的对象
     * @date 2022/7/15 9:11
     */
    public static void cglibBeanCopierCloneObject(Object source, Object target) {
        BeanCopierUtils.copyProperties(source, target);
    }
    /**
     * 对象与对象之间的数据转换
     *
     * @param source 转换的数据对象
     * @param target 需要转换数据的对象
     * @date 2022/7/15 9:11
     */
    public static <T> T cglibBeanCopierCloneObject(Object source, Class<T> target) {
        T t;
        try {
            t = target.newInstance();
            BeanCopierUtils.copyProperties(source, t);
        } catch (InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
        return t;
    }

    /**
     * 将list集合转换为传入的对象的数据集合
     *
     * @param sourceList 原数据集合
     * @param clazz      需要转换的集合数据对象
     * @return java.util.List<T>
     * @date 2022/4/6 13:49
     */
    public static <T> List<T> cloneList(List<?> sourceList, Class<T> clazz) {
        return cloneList(sourceList, clazz, true);
    }
    /**
     *
     * @date 2022/7/18 16:41
     * @param sourceList 原数据集合
     * @param clazz 需要转换的集合数据对象
     * @param whetherAssignNull 是否赋值空值:true是 false否
     * @return java.util.List<T>
     */
    public static <T> List<T> cloneList(List<?> sourceList, Class<T> clazz, Boolean whetherAssignNull) {
        try {
            List<T> targetList = new ArrayList<>(sourceList.size());
            for (Object source : sourceList) {
                if (whetherAssignNull) {
                    targetList.add(clone(source, clazz));
                } else {
                    targetList.add(clone(source, clazz, false));
                }
            }

            return targetList;
        } catch (Exception e) {
            LOGGER.error("数据转换异常", e);
            return null;
        }
    }


    /**
     * 获取需要忽略的属性
     */
    public static String[] getNullPropertyNames(Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        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);
    }
}
