package com.liangjian.dataplatform.member.util;

import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.*;

@Component
public class ToObject {

    /**
     * 将类中私有成员并有set方法的成员赋值
     * @param page List<Map<String,Object>>
     * @param clazz 该类
     * @param <T> 泛型
     * @return 该类集合
     * @throws InstantiationException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    public static <T> List<T> mapToObject(List<Map<String,Object>> page, Class<T> clazz) throws InstantiationException, InvocationTargetException, IllegalAccessException {
        Map<String,Method> fieldSetMethodMap = getObjFieldAndMethod(clazz);
        List<T> list=new ArrayList<>(page.size());
        if(page.size()>0){
            Object obj;
            for(Map<String,Object> row:page){
                obj=clazz.newInstance();
                for (Map.Entry<String, Object> item : row.entrySet()) {
                    if (fieldSetMethodMap.get(item.getKey()) != null)
                        fieldSetMethodMap.get(item.getKey()).invoke(obj, item.getValue());
                }
                list.add((T)obj);
            }
        }
        return list;
    }

    /**
     * 返回类中私有 非静态 有对应set方法的属性。它的属性和set方法集
     * @param clazz 类
     * @return 属性和set方法集
     */
    public static Map<String,Method> getObjFieldAndMethod(Class clazz){
        Map<String,Method> fieldSetMethodMap=new HashMap<>();
        List<Field> fieldList= new ArrayList<>(clazz.getDeclaredFields().length);
        fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
        Iterator<Field> iterator = fieldList.iterator();
        //筛选掉静态，公有的 无对应set方法的属性
        Field field;
        while (iterator.hasNext()){
            field= iterator.next();
            field.setAccessible(true);
            if(Modifier.isFinal(field.getModifiers())||Modifier.isStatic(field.getModifiers())||Modifier.isPublic(field.getModifiers())){
                iterator.remove();
                continue;
            }
            try{
                char firstUperChar= Character.toUpperCase(field.getName().charAt(0));
                byte[] fieldNameByte= field.getName().getBytes();
                byte[] firstUperCharByte=charToByte(firstUperChar);
                //英文字符只需要一个字节存储
                fieldNameByte[0]=firstUperCharByte[1];
                String methodName="set"+new String(fieldNameByte);
                if(clazz.getDeclaredMethod(methodName)==null){
                    iterator.remove();
                    continue;
                }
                fieldSetMethodMap.put(field.getName(),clazz.getDeclaredMethod(methodName));
            }catch (NoSuchMethodException e){
                iterator.remove();
                continue;
            }

        }
        return fieldSetMethodMap;
    }

    public static byte[] charToByte(char c) {
        byte[] b = new byte[2];
        b[0] = (byte) ((c & 0xFF00) >> 8);
        b[1] = (byte) (c & 0xFF);
        return b;
    }

    public static char byteToChar(byte[] b) {
        return (char) (((b[0] & 0xFF) << 8) | (b[1] & 0xFF));
    }
}
