package com.app.framework.core.support.convert;

import cn.hutool.core.util.TypeUtil;
import org.springframework.beans.BeanUtils;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;

/**
 * Entity转View工具类
 * 	用法：继承该类，并实现convert(E entity, V view)方法
 * 
 * @param <E> Entity
 * @param <V> View
 */
public abstract class ConvertViewUtils<E, V> {
	protected Class<V> viewClass;
	
	@SuppressWarnings("unchecked")
	public ConvertViewUtils() {
		viewClass = (Class) TypeUtil.getTypeArgument(getClass(), 1);
	}
	
	/**
	 * 将实体E转换成View，可忽略属性
	 * 返回页面时进行数据转换
	 * @param	entity	需要转换的Entity
	 */
	public V transform(E entity) {
		try {
			V view = viewClass.newInstance();
			if (entity != null) {
				BeanUtils.copyProperties(entity, view);
				convert(entity, view);
			}
			return view;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 将实体E转换成View，可忽略属性
	 * 返回页面时进行数据转换
	 * @param	entity	需要转换的Entity
	 * @param	ignoreProperties	需要忽略的属性
	 */
	public V transform(E entity, String... ignoreProperties) {
		try {
			V view = viewClass.newInstance();
			if (entity != null) {
				BeanUtils.copyProperties(entity, view, ignoreProperties);
				convert(entity, view);
			}
			return view;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 将实体E的集合转换成View的集合，可忽略属性
	 * 
	 * @param list	需要转换的数据集合
	 */
	public List<V> transform(List<E> list){
		int size = list != null ? list.size() : 0;
		List<V> result = new ArrayList<>(size);
		try {
			for (int i = 0; i < size; i++) {
				E entity = list.get(i);
				V view = viewClass.newInstance();
				BeanUtils.copyProperties(entity, view);
				convert(entity, view);
				result.add(view);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 将实体E的集合转换成View的集合，可忽略属性
	 * 
	 * @param list	需要转换的数据集合
	 * @param ignoreProperties	需要忽略的属性, 可选参数
	 */
	public List<V> transform(List<E> list, String... ignoreProperties) {
		int size = list != null ? list.size() : 0;
		List<V> result = new ArrayList<>(size);
		try {
			for (int i = 0; i < size; i++) {
				E entity = list.get(i);
				V view = viewClass.newInstance();
				BeanUtils.copyProperties(entity, view, ignoreProperties);
				convert(entity, view);
				result.add(view);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * 自定义转换(基类中已实现实体E到V的转换，该方法只需要实现其他附加的转换功能即可)
	 * @param entity 实体类对象
	 * @param view View对象
	 */
	public abstract void convert(E entity, V view) throws ParseException;

}
