package cn.superdesk.uniorder.common.numerical;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cglib.beans.BeanCopier;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;


@Slf4j
public class AnConvertBeanUtil {


	private static ConcurrentHashMap<String, BeanCopier> cache = new ConcurrentHashMap<String, BeanCopier>();


	/**
	 * 功能说明:将指定对象转成目标对象
	 *
	 * @param sourceObj
	 * @param target
	 * @return
	 * @createTime 2018年4月9日 下午4:58:01
	 * @author liuli
	 */
	public static <T> T copyBean(Object sourceObj, Class<T> target) {
		return copyBean(sourceObj, target, false);
	}


	/**
	 * 功能说明:将指定对象转成目标对象
	 *
	 * @param sourceObj
	 * @param target
	 * @param useConverter
	 * @return
	 * @createTime 2018年4月9日 下午4:56:08
	 * @author liuli
	 */
	public static <T> T copyBean(Object sourceObj, Class<T> target, boolean useConverter) {
		if (sourceObj == null || target == null) return null;
		String     key    = sourceObj.getClass().getSimpleName() + target.getSimpleName();
		BeanCopier copier = cache.get(key);
		if (copier == null) {
			copier = createBeanCopier(sourceObj.getClass(), target, useConverter, key);
		}
		T t = null;
		try {
			t = target.newInstance();
		} catch (InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		}
		copier.copy(sourceObj, t, null);
		return t;
	}


	/**
	 * 功能说明:将指定对象转成目标对象
	 *
	 * @param sourceObj
	 * @param target
	 * @param useConverter
	 * @return
	 * @createTime 2018年4月9日 下午4:55:38
	 * @author liuli
	 */
	public static <T> T copyBean(Object sourceObj, T target, boolean useConverter) {
		if (sourceObj == null || target == null) return null;
		String     key    = sourceObj.getClass().getSimpleName() + target.getClass().getSimpleName();
		BeanCopier copier = cache.get(key);
		if (copier == null) {
			copier = createBeanCopier(sourceObj.getClass(), target.getClass(), useConverter, key);
		}
		copier.copy(sourceObj, target, null);
		return target;
	}


	/**
	 * 功能说明: 将list转出指定泛型的list
	 *
	 * @param sourceObjs
	 * @param targetType
	 * @return
	 * @createTime 2018年4月9日 下午4:44:52
	 * @author liuli
	 */
	public static <T> List<T> copyListBeanToList(List<?> sourceObjs, Class<T> targetType) {
		List<T> targets = new ArrayList<T>();
		if (sourceObjs == null || targetType == null) return null;
		T t;
		for (Object o : sourceObjs) {
			try {
				t = targetType.newInstance();
				targets.add(copyBean(o, t, false));
			} catch (InstantiationException e) {
				log.error("", e);
			} catch (IllegalAccessException e) {
				log.error("", e);
			}
		}
		return targets;
	}


	@SuppressWarnings({"rawtypes"})
	private static BeanCopier createBeanCopier(Class sourceClass, Class targetClass, boolean useConverter, String cacheKey) {
		BeanCopier copier = BeanCopier.create(sourceClass, targetClass, useConverter);
		cache.putIfAbsent(cacheKey, copier);
		return copier;
	}
}
