package cn.freemud.platform.sdk.common.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.MessageDigest;
import java.util.*;

public class HualalaSignUtil {
    static final Logger logger = LoggerFactory.getLogger(HualalaSignUtil.class);
    public static final String SIGNATURE_SECRET_KEY = "devPwd";
    public static final String SIGNATURE_PREFIX = "key";
    public static final String SIGNATURE_SUFFIX = "secret";

    public HualalaSignUtil() {
    }

    public static <T> String getSignature(T commonRequest, Object requestBody, String devPwd, String logPrefix) throws Exception {
        try {
            Map<String, Object> fieldMap = new TreeMap(new Comparator<String>() {
                public int compare(String o1, String o2) {
                    return o1.compareToIgnoreCase(o2);
                }
            });

            Map<String, Object> fieldMapHeader = new TreeMap(new Comparator<String>() {
                public int compare(String o1, String o2) {
                    return o1.compareToIgnoreCase(o2);
                }
            });
            fieldMapHeader = getPropertyObject(commonRequest, fieldMapHeader);
            fieldMap = getPropertyObject(requestBody, fieldMap);
            fieldMap.put("devPwd", devPwd);
            fieldMap.putAll(fieldMapHeader);
            if (fieldMap.size() <= 0) {
                return null;
            } else {
                StringBuilder loggerSb = new StringBuilder();
                StringBuilder sb = new StringBuilder();
                sb.append("key");

                String key;
                Object fieldValue;
                for (Iterator var6 = fieldMap.keySet().iterator(); var6.hasNext(); loggerSb.append(key + ": " + fieldValue + " ")) {
                    key = (String) var6.next();
                    fieldValue = fieldMap.get(key);
                    sb.append(key).append(fieldValue);
                    if (StringUtils.isEmpty(logPrefix)) {
                        loggerSb.append(logPrefix + " ");
                    }
                }

                sb.append("secret");
                String generatorStr = sb.toString();
                key = getSha1(generatorStr);
                logger.info("generator str: " + generatorStr + ", generator signature: " + key);
                return key;
            }
        } catch (Exception var9) {
            logger.error("generator signature util error", var9);
            throw new Exception(var9);
        }
    }

    public static Map<String, Object> getPropertyObject(Object field, Map<String, Object> treeMap) throws Exception {
        boolean isBaseTypeObjec = isBaseTypeObject(field);
        if (isBaseTypeObjec) {
            return treeMap;
        } else {
            for (Class sub = field.getClass(); sub != Object.class; sub = sub.getSuperclass()) {
                Field[] subFields = sub.getDeclaredFields();

                for (int i = 0; i < subFields.length; ++i) {
                    Field currtField = subFields[i];
                    Boolean sc = currtField.isAccessible();
                    currtField.setAccessible(true);
                    if (currtField.getType().isAssignableFrom(List.class)) {
                        List<Object> listClass = (List) currtField.get(field);
                        if (listClass != null && listClass.size() > 0) {
                            treeMap = getPropertyObject(listClass.get(0), treeMap);
                        }
                    } else {
                        boolean isBaseType = isBaseType(currtField);
                        if (!isBaseType && currtField.get(field) != null) {
                            treeMap = getPropertyObject(currtField.get(field), treeMap);
                        } else {
                            String sFieldName = currtField.getName();
                            Object sFieldValue = getFieldValueByName(sFieldName, field);
                            if (sFieldValue != null) {
                                treeMap.put(sFieldName, sFieldValue);
                            }
                        }

                        currtField.setAccessible(sc);
                    }
                }
            }

            return treeMap;
        }
    }

    public static boolean isBaseType(Field field) {
        if (field.getType().isAssignableFrom(Integer.class)) {
            return true;
        } else if (field.getType().isAssignableFrom(Character.class)) {
            return true;
        } else if (field.getType().isAssignableFrom(Short.class)) {
            return true;
        } else if (field.getType().isAssignableFrom(Long.class)) {
            return true;
        } else if (field.getType().isAssignableFrom(Double.class)) {
            return true;
        } else if (field.getType().isAssignableFrom(Float.class)) {
            return true;
        } else if (field.getType().isAssignableFrom(Boolean.class)) {
            return true;
        } else if (field.getType().isAssignableFrom(Byte.class)) {
            return true;
        } else {
            return field.getType().isAssignableFrom(String.class);
        }
    }

    public static boolean isBaseTypeObject(Object object) {
        if (object instanceof Integer) {
            return true;
        } else if (object instanceof Character) {
            return true;
        } else if (object instanceof Short) {
            return true;
        } else if (object instanceof Long) {
            return true;
        } else if (object instanceof Double) {
            return true;
        } else if (object instanceof Float) {
            return true;
        } else if (object instanceof Byte) {
            return true;
        } else {
            return object instanceof String;
        }
    }

    private static Object getFieldValueByName(String fieldName, Object obj) {
        Object value = null;

        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = obj.getClass().getMethod(getter);
            value = method.invoke(obj);
        } catch (Exception var6) {
            var6.printStackTrace();
        }

        return value;
    }

    public static String getSha1(String encryptStr) throws Exception {
        try {
            if (StringUtils.isEmpty(encryptStr)) {
                return null;
            } else {
                MessageDigest digest = MessageDigest.getInstance("SHA-1");
                digest.update(encryptStr.getBytes());
                byte[] messageDigest = digest.digest();
                StringBuffer hexString = new StringBuffer();

                for (int i = 0; i < messageDigest.length; ++i) {
                    String shaHex = Integer.toHexString(messageDigest[i] & 255);
                    if (shaHex.length() < 2) {
                        hexString.append(0);
                    }

                    hexString.append(shaHex);
                }

                return hexString.toString().toUpperCase();
            }
        } catch (Exception var6) {
            var6.printStackTrace();
            throw new Exception(var6);
        }
    }
}
