package jnpf.util;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import jnpf.annotation.check.CheckLength;
import jnpf.annotation.check.CheckListSize;
import jnpf.annotation.check.CheckNull;
import jnpf.exception.HandleException;

import java.lang.reflect.Field;
import java.util.List;

/**
 * 参数校验
 */
public class ParamUtil {

    /**
     * 参数校验
     * @param t
     */
    public static void checkParam(Object t) throws Exception{
//        Class<T> aClass = ClassUtil.getClass(t);
        Class<?> aClass = t.getClass();
        Field[] fields = aClass.getDeclaredFields();

        for (Field field : fields) {
            /** 校验字段是否是空*/
            CheckNull annotation = field.getAnnotation(CheckNull.class);
            if (annotation == null) {
                continue;
            }
            field.setAccessible(true);
            Class<?> type = field.getType();
            if (type == String.class) {
                /** 字符串类型*/
                try {
                    Object o = field.get(t);
                    String s = ObjectUtil.isNull(o) ? null : String.valueOf(o);
                    if (StrUtil.isBlank(s)) {
                        throw new HandleException(annotation.message());
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }else {
                /** 普通对象类型*/
                try {
                    if (field.get(t) == null) {
                        throw new HandleException(annotation.message());
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (HandleException e) {
                    throw new RuntimeException(e);
                }
            }
        }

        for (Field field : fields) {
            field.setAccessible(true);
            /** 校验字段长度*/
            CheckLength checkLength = field.getAnnotation(CheckLength.class);
            if (checkLength == null) {
                continue;
            }
            int max = checkLength.max();
            int min = checkLength.min();
            try {
                Object o = field.get(t);
                String str = String.valueOf(o);
                if (StrUtil.length(str) > max && max > 0) {
                    throw new HandleException(checkLength.message());
                }
                if (StrUtil.length(str) < min && min > 0) {
                    throw new HandleException(checkLength.message());
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        /** 检查数组长度*/
        for (Field field : fields) {
            check(field, t);
//            field.setAccessible(true);
//            CheckListSize listSize = field.getAnnotation(CheckListSize.class);
//            if (listSize == null) {
//                continue;
//            }
//            try {
//                Object o = field.get(t);
//                if (o instanceof List) {
//                    List list = (List) o;
//                    if (CollectionUtil.isEmpty(list)) {
//                        throw new ApiException(listSize.message());
//                    }
//                }
//            } catch (IllegalAccessException e) {
//                e.printStackTrace();
//            }
        }
    }

    private static <T, R> void check(Field field, T t) throws Exception{
        field.setAccessible(true);
        CheckListSize listSize = field.getAnnotation(CheckListSize.class);
        if (listSize != null) {
            try {
                Object o = field.get(t);
                if (ObjectUtil.isNull(o)) {
                    throw new HandleException(listSize.message());
                }
                if (o instanceof List) {
                    List list = (List) o;
                    if (CollectionUtil.isEmpty(list)) {
                        throw new HandleException(listSize.message());
                    }
                }
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
}
