package com.siwei.common.core.utils.bean;

import com.siwei.common.core.utils.StringUtils;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

/**
 * 通过bean,进行放射调用
 */
public class BeanReflectionUtils {

    public static Object invokeMethodV1(String bean, String methodName, List<Object> methodParams) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, ClassNotFoundException {
        Class<?> classBean = Class.forName(bean);
        return invokeMethodV1(classBean, methodName, methodParams);
    }

    /**
     * 调用方法
     *
     * @param bean         目标对象
     * @param methodName   方法名称
     * @param methodParams 方法参数
     */
    public static Object invokeMethodV1(Object bean, String methodName, List<Object> methodParams) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0) {
            Method method = bean.getClass().getMethod(methodName, getMethodParamsType(methodParams));
            return method.invoke(bean, getMethodParamsValue(methodParams));
        } else {
            Method method = bean.getClass().getMethod(methodName);
            return method.invoke(bean);
        }
    }


//    public static Object invokeMethodV2(String bean, String methodName, List<Object[]> methodParams) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException, ClassNotFoundException {
//        Class<?> classBean = Class.forName(bean);
//        return invokeMethodV2(classBean, methodName, methodParams);
//    }
//
//    /**
//     * 调用方法
//     *
//     * @param bean         目标对象
//     * @param methodName   方法名称
//     * @param methodParams 方法参数
//     */
//    public static Object invokeMethodV2(Object bean, String methodName, List<Object[]> methodParams) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
//        if (StringUtils.isNotNull(methodParams) && methodParams.size() > 0) {
//            Method method = bean.getClass().getMethod(methodName, getMethodParamsTypeV2(methodParams));
//            return method.invoke(bean, getMethodParamsValueV2(methodParams));
//        } else {
//            Method method = bean.getClass().getMethod(methodName);
//            return method.invoke(bean);
//        }
//    }

    /**
     * 获取参数类型
     *
     * @param methodParams 参数相关列表
     * @return 参数类型列表
     */
    private static Class<?>[] getMethodParamsTypeV2(List<Object[]> methodParams) {
        Class<?>[] classs = new Class<?>[methodParams.size()];
        int index = 0;
        for (Object[] os : methodParams) {
            classs[index] = (Class<?>) os[1];
            index++;
        }
        return classs;
    }

    /**
     * 获取参数类型
     *
     * @param methodParams 参数相关列表
     * @return 参数类型列表
     */
    private static Class<?>[] getMethodParamsType(List<Object> methodParams) {
        Class<?>[] classs = new Class<?>[methodParams.size()];
        int index = 0;
        for (Object os : methodParams) {
            classs[index] = (Class<?>) os;
            index++;
        }
        return classs;
    }


    /**
     * 获取参数值
     *
     * @param methodParams 参数相关列表
     * @return 参数值列表
     */
    private static Object[] getMethodParamsValueV2(List<Object[]> methodParams) {
        Object[] classs = new Object[methodParams.size()];
        int index = 0;
        for (Object[] os : methodParams) {
            classs[index] = (Object) os[0];
            index++;
        }
        return classs;
    }

    /**
     * 获取参数值
     *
     * @param methodParams 参数相关列表
     * @return 参数值列表
     */
    private static Object[] getMethodParamsValue(List<Object> methodParams) {
        Object[] classs = new Object[methodParams.size()];
        int index = 0;
        for (Object os : methodParams) {
            classs[index] = (Object) os;
            index++;
        }
        return classs;
    }

}
