package com.huatek.busi.common.util;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.google.common.base.Objects;
import com.huatek.torch.sql.annotation.FieldName;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Tools {

    /**
     * Map->Bean
     * 
     * @param source
     * @param instance
     * @return
     */
    public static <T> T mapToBean(Map<String, Object> source, Class<T> instance) {
        try {
            T object = instance.newInstance();
            Field[] fields = object.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                String key = field.getName();
                if (StringUtils.isNotEmpty(key) && "serialVersionUID".equals(key)) {
                    continue;
                }
                FieldName fieldName = field.getAnnotation(FieldName.class);
                if (fieldName != null) {
                    field.set(object, source.get(fieldName.value()));
                } else {
                    field.set(object, source.get(field.getName()));
                }
            }
            return object;
        } catch (InstantiationException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Map<String, Object> beanToMap(Object target, String... ignoredFields) {
        if(target == null) {
            return null;
        }
        try {
            // 获取javaBean的BeanInfo对象
            BeanInfo beanInfo = Introspector.getBeanInfo(target.getClass(), Object.class);
            // 获取属性描述器
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
            Map<String, Object> resultMap = new LinkedHashMap<>(propertyDescriptors.length);
            for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
                // 获取属性名
                String key = propertyDescriptor.getName();
                if(isIgnore(ignoredFields, key)) {
                    continue;
                }
                // 获取该属性的值
                Method readMethod = propertyDescriptor.getReadMethod();
                // 通过反射来调用javaBean定义的getName()方法
                resultMap.put(key, readMethod.invoke(target));
            }
            return resultMap;
        } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException
            | IntrospectionException e) {
            log.error(e.getMessage(), e);
            return null;
        }
    }

    private static boolean isIgnore(String[] ignoredFields, String key) {
        if(ignoredFields == null || ignoredFields.length == 0) {
            return false;
        }
        for(String ignoreKey : ignoredFields) {
            if(Objects.equal(ignoreKey, key)) {
                return true;
            }
        }
        return false;
    }

    public static String popString(Map<String, Object> map, String key) {
        return (String)map.remove(key);
    }

    public static void append(final StringBuilder warningMsg, String msg) {
        if (warningMsg.length() > 0) {
            warningMsg.append("；");
        }
        warningMsg.append(msg);
    }
    
    /**
     * 字符串反转
     * @param str
     * @return
     */
    public static String strReverse(String str)
    {
        return new StringBuffer(str).reverse().toString();
    }
}