package com.artfess.base.util;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Java反射工具类
 * 
 * @开发公司：广州宏天软件股份有限公司
 * @作者：mikel
 * @邮箱：mouhb@jee-soft.cn
 * @创建时间：2020年10月23日
 */
public class ReflectUtil {
	
	/**
	 * 获取某个类的所有属性
	 * @param clazz
	 * @return
	 */
	public static List<Field> getAllField(Class<?> clazz){
		List<Field> fields = new ArrayList<>();
		while (clazz!=null){
			fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
			clazz = clazz.getSuperclass();
		}
		return fields;
	}
	
	/**
	 * 为指定对象的属性设值
	 * @param object
	 * @param field
	 * @param value
	 * @throws Exception
	 */
	public static void setFieldValue(Object object, Field field, Object value) throws Exception{
		field.setAccessible(true);
        field.set(object, value);
	}

	/**
	 * 获取泛型的类型
	 * @param type
	 * @return
	 */
	public static Class<?> getGenericType(Type type, int index) {
		if (type instanceof ParameterizedType) {
			ParameterizedType pt = (ParameterizedType) type;
			Type genericTypeArr[] = pt.getActualTypeArguments();
			if (genericTypeArr.length > index) {
				return (Class<?>) genericTypeArr[index];
			}
		}
		return null;
	}
	
	/**
	 * 判断一个类是否是基础类型
	 * @param clazz
	 * @return
	 */
	public static boolean isBasicType(Class<?> clazz) {
		switch (clazz.getSimpleName().toLowerCase()) {
		case "string":
		case "boolean":
		case "byte":
		case "short":
		case "int":
		case "long":
		case "float":
		case "double":
		case "date":
		case "localdate":
		case "localdateTime":
			return true;
		default:
			return false;
		}
	}
	
	/**
	 * 获取原始类型的默认值
	 * @param clazz
	 * @return
	 */
	public static Object getPrimitiveDefaultValue(Class<?> clazz) {
		switch (clazz.getSimpleName().toLowerCase()) {
		case "boolean":
			return false;
		case "byte":
			return (byte) 0;
		case "short":
			return (short) 0;
		case "int":
			return (int) 0;
		case "long":
			return (long) 0;
		case "float":
			return (float) 0;
		case "double":
			return (double) 0;
		case "char":
			return (char) 0;
		default:
			return null;
		}
	}
}
