package com.younike.hlpay.util;

import com.younike.hlpay.constant.HeliPayContants;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.beans.IntrospectionException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;

/**
 *
 */
public class BeanUtils {

    private static final Logger LOGGER = LoggerFactory.getLogger(BeanUtils.class);

    private BeanUtils(){ }

    public static Map convertBean(Object bean, Map retMap)
            throws IntrospectionException, IllegalAccessException, InvocationTargetException {
        Class clazz = bean.getClass();
        Field[] fields = clazz.getDeclaredFields();
        for (Field f : fields) {
            f.setAccessible(true);
        }
        for (Field f : fields) {
            String key = f.toString().substring(f.toString().lastIndexOf(".") + 1);
            if (StringUtils.equalsIgnoreCase("NEED_SIGN_PARAMS", key)) {
                continue;
            }
            Object value = f.get(bean);
            if (value == null)
                value = "";
            retMap.put(key, value);
        }
        return retMap;
    }

    public static String getSigned(Map<String, String> map, String[] excludes){
        StringBuffer sb = new StringBuffer();
        Set<String> excludeSet = new HashSet<String>();
        excludeSet.add("sign");
        if(excludes != null){
            for(String exclude : excludes){
                excludeSet.add(exclude);
            }
        }
        for(String key : map.keySet()){
            if(!excludeSet.contains(key)){
                String value = map.get(key);
                value = (value == null ? "" : value);
                sb.append(HeliPayContants.SPLIT);
                sb.append(value);
            }
        }
        sb.append(HeliPayContants.SPLIT);
        sb.append(HeliPayContants.SIGNKEY_MD5);
        return sb.toString();
    }

    public static String getSigned(Object bean, String[] excludes) throws IllegalAccessException, IntrospectionException, InvocationTargetException {
        Map map  = convertBean(bean, new LinkedHashMap());
        String signedStr = getSigned(map, excludes);
        return signedStr;
    }

    /**
     * new style
     *
     * @param bean
     * @param needSignParams
     */
    public static String getSignedByPresetParameter(Object bean, Set<String> needSignParams) throws IllegalAccessException,
            IntrospectionException, InvocationTargetException {
        Map map = convertBean(bean, new LinkedHashMap<>());
        return getSignedByPresetParameter(map, needSignParams);
    }

    /**
     * new style
     *
     * @param map
     * @param needSignParams
     * @return
     */
    public static String getSignedByPresetParameter(Map<String, String> map, Set<String> needSignParams) {
        StringBuffer sb = new StringBuffer();
        if (needSignParams == null || needSignParams.isEmpty()) {
            throw new RuntimeException("needSignParams is required");
        }
        for (String key : map.keySet()) {
            if (needSignParams.contains(key)) {
                // do sign
                String value = map.get(key);
                value = (value == null ? "" : value);
                sb.append(HeliPayContants.SIGN_SPLIT);
                sb.append(value);
            }
        }
        sb.append(HeliPayContants.SIGN_SPLIT).append(HeliPayContants.SIGNKEY_MD5);
        return sb.toString();
    }

}
