package com.mortals.xhx.common.utils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

public class BeanUtil {

    protected static Logger log = LoggerFactory.getLogger(BeanUtil.class);

    public static <SOURCE, TARGET> List<TARGET> covertList(List<SOURCE> srcList, Class<TARGET> clazz) {
        List<TARGET> retList = new ArrayList<>();
        if (srcList == null || srcList.isEmpty()) {
            return retList;
        }
        for (SOURCE source : srcList) {
            TARGET target;
            try {
                target = clazz.newInstance();
                if (source == null) {
                    continue;
                }
                BeanUtils.copyProperties(source, target);
                retList.add(target);
            } catch (InstantiationException | IllegalAccessException e) {
                log.error("", e);
            }
        }
        return retList;
    }

    public static <SOURCE, TARGET> TARGET covert(SOURCE source, Class<TARGET> clazz) {
        TARGET target = null;
        if (source == null) {
            return target;
        }
        try {
            target = clazz.newInstance();
            BeanUtils.copyProperties(source, target);
        } catch (InstantiationException | IllegalAccessException e) {
            log.error("", e);
        }
        return target;
    }

    @SuppressWarnings({ "rawtypes", "unused", "unchecked" })
    public static final Map entityToMap(Object entity) {
        Map map = new HashMap<>();
        try {
            Class cls = entity.getClass();
            BeanInfo beanInfo = Introspector.getBeanInfo(cls);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (int i = 0; i < propertyDescriptors.length; i++) {
                PropertyDescriptor descriptor = propertyDescriptors[i];
                String propertyName = descriptor.getName();
                if (!propertyName.equals("class") && !propertyName.equals("orderCols")
                        && !propertyName.equals("notSelectCols") && !propertyName.equals("symbolCols")
                        && !propertyName.equals("vague")) {
                    Method readMethod = descriptor.getReadMethod();
                    Object result = readMethod.invoke(entity, new Object[0]);
                    if (result != null) {
                        String className = result.getClass().getSimpleName();
                        map.put(propertyName, result);
                        /*
                         * if(result instanceof String){
                         * if(((String)result).trim().length() > 0){
                         * map.put(propertyName, result); } }else{
                         * map.put(propertyName, result); }
                         */
                    }
                }
            }
        } catch (Exception e) {
            log.warn("将对象转换成Map异常-->" + entity + "-->" + e.getMessage());
        }
        return map;
    }

    public static final <T> T mapToEntity(Map<?, ?> map, Class<T> clz) {
        T target = null;
        try {
            target = clz.newInstance();
            BeanInfo beanInfo = Introspector.getBeanInfo(clz);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            for (int i = 0; i < propertyDescriptors.length; i++) {
                PropertyDescriptor descriptor = propertyDescriptors[i];
                String propertyName = descriptor.getName();

                if (map.containsKey(propertyName)) {
                    Object value = map.get(propertyName);
                    Object[] args = new Object[1];
                    args[0] = value;
                    descriptor.getWriteMethod().invoke(target, args);
                }
            }
        } catch (Exception e) {
            log.warn("将Map转换成对象异常-->" + clz + "-->" + e.getMessage());
        }
        return target;
    }

    /**
     *
     * @Title: getNullPropertyNames
     * @Description: 获取一个对象中属性值为null的属性名字符串数组
     * @param source
     * @return
     */
    public static String[] getNullPropertyNames (Object source) {
        final BeanWrapper src = new BeanWrapperImpl(source);
        java.beans.PropertyDescriptor[] pds = src.getPropertyDescriptors();
        Set<String> emptyNames = new HashSet<String>();
        for(java.beans.PropertyDescriptor pd : pds) {
            Object srcValue = src.getPropertyValue(pd.getName());
            if (srcValue == null) emptyNames.add(pd.getName());
        }
        String[] result = new String[emptyNames.size()];
        return emptyNames.toArray(result);
    }


    /**
     *      * 校验特殊字符
     *      * @param str
     *      * @return
     *      
     */
    public static  boolean  isConSpeChar(String str) {
        String regEx = "[`~'\"?~？]";
        Pattern p = Pattern.compile(regEx);
        Matcher m = p.matcher(str);
        return m.find();
    }

    public static void main(String[] args) {

        String str="'";
        System.out.println(BeanUtil.isConSpeChar(str));

        ObjectMapper mapper = new ObjectMapper();
        //Map<String, String> map = mapper.readValue(json, Map.class);
    }

}
