package com.bohuikeji.frame.module.admin.utils;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.bohuikeji.frame.module.admin.base.EntityBase;
import com.bohuikeji.frame.module.admin.base.SuperBase;
import com.google.common.base.CaseFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * 反射工具类
 * @author 10552
 */
public final class  ReflectUtil extends SuperBase {
    protected static transient Logger log = LoggerFactory.getLogger(ReflectUtil.class);
    /**
     * 获取该对象具有指定注解的字段列表
     *
     * @param annotationClass
     * @return
     */
    public static List<Field> getFieldsByAnnotation(Class<?> clazz, Class<? extends Annotation> annotationClass) {
        List<Field> fieldList = new ArrayList<>(16);
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            if (field.isAnnotationPresent(annotationClass)) {
                fieldList.add(field);
            }
        }
        return fieldList;
    }

    /**
     * 为实体字段设置值
     * @param entity 被设置的实体对象
     * @param field 实体字段
     * @param value 字段值
     */
    public static void setValue(EntityBase entity, Field field, Object value){
        String filedName = field.getName();
        String methodName = "set" + filedName.substring(0,1).toUpperCase()+filedName.substring(1);
        Method method =null;
        try{
            method =  entity.getClass().getDeclaredMethod(methodName, field.getType());
            method.invoke(entity, value);
        }catch(Exception ex){
            log.error("无法为实体[{}]设置属性：[{}]=[{}]，调用方法:[{}]", entity.getClass().getName(), field.getName(), value,method, ex);
        }
    }


    /**
     * 获取实体类的对应表名称
     * @param cls
     * @return
     */
    public static String getTableName(Class<? extends EntityBase> cls) {
        TableName tableName = cls.getAnnotation(TableName.class);
        if (tableName != null) {
            if (StringUtils.isNotBlank(tableName.value())) {
                return tableName.value();
            }
        }
        return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, cls.getSimpleName());
    }

    /**
     * 获取字段对应的数据库列字段
     * @param field
     * @return
     */
    public static String getColumnName(Field field){
        TableField tableField=field.getAnnotation(TableField.class);
        if(tableField==null){
            return null;
        }
        if(!tableField.exist()){
            return null;
        }
        if(StringUtils.isNotBlank(tableField.value())){
            return tableField.value();
        }
        return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName());
    }


}
