package com.weiqi.mis;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.impl.DefaultMapperFactory;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StopWatch;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

// import com.weiqi.chat.common.model.FilePart;

/**
 * Created by lindaohui on 2018/3/22.
 */
public final class Z {

    private final static Logger logger = LoggerFactory.getLogger(Z.class);
    public static ObjectMapper objectMapper;
    public static MapperFacade orikaMapper;

    /**
     * 服务器 IP
     */
    public static final String SERVER_IP;

    static {

        String hostAddress;
        try {
            hostAddress = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            hostAddress = "Unknown";
        }
        SERVER_IP = hostAddress;
    }

    /**
     * 默认时间格式
     */
    private static final SimpleDateFormat defaultDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    static {
        // jackson
        objectMapper = new ObjectMapper();
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); // 缺字段不报异常
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        // objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); // 加 @class
        // 信息
        // objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); // 驼峰变下滑线
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        // orika
        MapperFactory mapperFactory = new DefaultMapperFactory.Builder().build();
        orikaMapper = mapperFactory.getMapperFacade();
    }

    /**
     * 字符串合并方法，返回一个合并后的字符串,像.net里的format函数
     *
     * @param str
     * @param args
     * @return
     */
    public static String fmt(String str, Object... args) {
        if (str == null || "".equals(str) || args.length == 0)
            return str;

        String result = str.intern();
        Pattern p = Pattern.compile("\\{(\\d+)\\}");
        java.util.regex.Matcher m = p.matcher(str);

        while (m.find()) {
            int index = Z.parseInt(m.group(1));
            if (index < args.length) {
                result = result.replace(m.group(), args[index] == null ? "" : args[index].toString());
            }
        }
        return result;
    }

    public static int parseInt(String s) {
        return parseInt(s, 0);
    }

    public static Integer parseInt(String s, int def) {
        try {
            return Integer.parseInt(s);
        } catch (NumberFormatException e) {
            return def;
        }
    }

    public static <T> T fromJSON(final TypeReference<T> typeReference, final String jsonString) throws Exception {
        T data = Z.objectMapper.readValue(jsonString, typeReference);
        return data;
    }

    public static <T> T fromJSON(final Class<T> tClass, final String jsonString) throws Exception {
        T data = Z.objectMapper.readValue(jsonString, tClass);
        return data;
    }

    public static String toJSON(Object val) throws Exception {
        String str = Z.objectMapper.writeValueAsString(val);
        return str;
    }

    public static String safeToJSON(Object val) {
        String str = "";
        try {
            str = Z.toJSON(val);
        } catch (Exception e) {
            logger.debug("toJSON 发生异常，errMsg：{}，val：{}", e.getMessage(), val, e);
        }
        return str;
    }

    public static <T> T safeFromJSON(final Class<T> tClass, final String jsonString) {
        T data = null;
        try {
            data = Z.objectMapper.readValue(jsonString, tClass);
        } catch (IOException e) {
            logger.debug("safeFromJSON 发生异常，errMsg：{}，jsonString：{}", e.getMessage(), jsonString, e);
        }
        return data;
    }

    /**
     * 简单的复制出新类型对象
     *
     * @param source
     * @param destinationClass
     * @param <S>
     * @param <D>
     * @return
     */
    public static <S, D> D map(S source, Class<D> destinationClass) {
        return orikaMapper.map(source, destinationClass);
    }

    /**
     * 简单的复制出新类型对象
     *
     * @param source
     * @param destinationClass
     * @param <S>
     * @param <D>
     * @return
     */
    public static <S, D> List<D> mapAsList(Iterable<S> source, Class<D> destinationClass) {
        return orikaMapper.mapAsList(source, destinationClass);
    }

    // /**
    // * @param min 这个正则过于严格，无法满足需求
    // * 最小值
    // * @param max
    // * 最大值，会返回最大值
    // * @return
    // */
    // public static int getRandom(int min, int max) {
    // return (int)(min + Math.random() * (max - min + 1));
    // }
    //
    // public static boolean isMobile(String mobile) {
    // if (mobile == null) {
    // return false;
    // }
    // Pattern pattern = Pattern.compile("^0?1[34578]\\d{9}$");
    // Matcher matcher = pattern.matcher(mobile);
    // return matcher.matches();
    // }

    public static boolean isNullOrEmpty(String content) {
        return content == null || content.length() == 0;
    }

    /**
     * 是否为 null 或者小于1
     *
     * @param value
     * @return
     */
    public static boolean isNullOrLessOne(Integer value) {
        return value == null || value < 1;
    }

    /**
     * 是否为 null 或者长度为0
     *
     * @param collection
     * @return
     */
    public static boolean isNullOrEmpty(Collection collection) {
        return collection == null || collection.size() == 0;
    }

    public static String getIpAddress(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("F443CIP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CIP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            if (!isNullOrEmpty(ip)) {
                ip = ip.split(",")[0];
            }
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("REMOTE_ADDR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CDN_SRC_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        if (ip != null && ip.startsWith("::")) {
            ip = "127.0.0.1";
        }
        return ip;
    }

    /**
     * 获取本地主机名字
     *
     * @return
     */
    public static String getLocalHostName() {
        try {
            return InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            return "unknown";
        }
    }

    public static String getParameter(HttpServletRequest request, String name) {
        Enumeration<String> parameterNames = request.getParameterNames();
        while (parameterNames.hasMoreElements()) {
            String key = parameterNames.nextElement();
            if (name.equalsIgnoreCase(key)) {
                return request.getParameter(key);
            }
        }
        return "";
    }

    public static int getParameterForInt(HttpServletRequest request, String name, int defaultValue) {
        String str = getParameter(request, name);
        if (isNullOrEmpty(str)) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(str);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    public static Cookie getCookie(Cookie[] cookies, String name) {
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (name.equalsIgnoreCase(cookie.getName())) {
                    return cookie;
                }
            }
        }
        return null;
    }

    public static String joinString(Object[] array, String regex) {
        int length = array.length;
        if (length < 1) {
            return "";
        }
        if (length == 1) {
            return array[0].toString();
        }
        StringBuilder sb = new StringBuilder(array[0].toString());
        for (int i = 1; i < length; i++) {
            sb.append(regex);
            sb.append(array[i]);
        }
        return sb.toString();
    }

    public static String formatLogContent(String url, String queryString, String message) {

        String args = message;
        if (url != null && !url.isEmpty()) {
            args += "," + Z.safeURLEncode(url);
        }
        if (queryString != null && !queryString.isEmpty()) {
            args += "," + Z.safeURLEncode(queryString);
        }
        return args;
        // SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd*HH:mm:ss");
        // String args = "host_str=&url_str=" + url + "&query_str=";
        // try {
        // args += URLEncoder.encode(queryString, "utf-8");
        // } catch (Exception e) {
        // }
        // return String.format("`%s`cyqchat`%s`%s", simpleDateFormat.format(new Date()).replace('*', 'T'), args,
        // message);
    }

    public static String formatLogContent(String message) {
        return formatLogContent("", "", message);
    }

    public static String httpGet(String url) throws Exception {
        return httpGet(url, 0, "utf-8", null);
    }

    public static String httpGet(String url, Map<String, String> headerMap) throws Exception {
        return httpGet(url, 0, "utf-8", headerMap);
    }

    public static String httpGet(String url, Integer timeout, String receiveEncoding) throws Exception {
        return httpGet(url, timeout, receiveEncoding, null);
    }

    public static String httpGet(String url, Integer timeout, String receiveEncoding, Map<String, String> headerMap)
        throws Exception {
        if (isNullOrEmpty(url)) {
            throw new Exception("url is empty");
        }

        logger.debug("httpGet url:{}, timeout:{}, receiveEncoding:{}, headerMap:{}", url, timeout, receiveEncoding,
            headerMap);
        // 计时开始
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 调用接口
        URL httpUrl = new URL(url);
        HttpURLConnection httpConnection = (HttpURLConnection)httpUrl.openConnection();
        httpConnection.setRequestMethod("GET");
        if (timeout > 0) {
            httpConnection.setConnectTimeout(timeout);
            httpConnection.setReadTimeout(timeout);
        }
        if (headerMap != null) {
            for (Map.Entry<String, String> mapEntry : headerMap.entrySet()) {
                httpConnection.setRequestProperty(mapEntry.getKey(), mapEntry.getValue());
            }
        }
        httpConnection.setRequestProperty("Accept-Charset", receiveEncoding);
        BufferedReader inputBufferedReader = new BufferedReader(new InputStreamReader(
            httpConnection.getResponseCode() == 200 ? httpConnection.getInputStream() : httpConnection.getErrorStream(),
            receiveEncoding));
        StringBuilder sb = new StringBuilder();
        String readLine = null;
        while ((readLine = inputBufferedReader.readLine()) != null) {
            sb.append(readLine);
            // sb.append("\r\n");
        }
        inputBufferedReader.close();
        httpConnection.disconnect();
        // 计时结束
        stopWatch.stop();
        Long pastTime = stopWatch.getLastTaskTimeMillis();
        if (pastTime > 200) {
            logger.warn(formatLogContent(url, "", "request tired - httpGet, " + pastTime + "ms"));
        }

        logger.debug("httpGet response：{}", sb.toString());
        return sb.toString();
    }

    /**
     * 获取请求响应状态码
     *
     * @param url
     * @param timeout
     * @return
     * @throws IOException
     */
    public static Integer httpGetResponseCode(String url, Integer timeout) {

        Integer code;
        try {
            URL httpUrl = new URL(url);
            HttpURLConnection httpConnection = (HttpURLConnection)httpUrl.openConnection();
            if (timeout > 0) {
                httpConnection.setConnectTimeout(timeout);
                httpConnection.setReadTimeout(timeout);
            }
            httpConnection.setRequestMethod("GET");

            code = httpConnection.getResponseCode();

            httpConnection.disconnect();

        } catch (IOException e) {
            code = 500;
            logger.error("获取请求响应状态码发送异常，errMsg：{}，url：{}，timeout：{}", e.getMessage(), url, timeout, e);
        }

        return code;

    }

    public static String httpPost(String url, String data, Map<String, String> headerMap) throws Exception {
        return httpPost(url, 0, "utf-8", "utf-8", data, headerMap);
    }

    public static String httpPost(String url, Integer timeout, String sendEncoding, String receiveEncoding, String data,
        Map<String, String> headerMap) throws Exception {
        if (isNullOrEmpty(url)) {
            throw new Exception("url is empty");
        }

        logger.debug("发起 HTTP POST 请求，请求地址：{}，超时时间：{}，发送编码：{}，接收编码：{}，数据：{}，请求头：{}", url, timeout, sendEncoding,
            receiveEncoding, data, headerMap);
        // 计时开始
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        // 调用接口
        URL httpUrl = new URL(url);
        HttpURLConnection httpConnection = (HttpURLConnection)httpUrl.openConnection();
        httpConnection.setRequestMethod("POST");
        if (timeout > 0) {
            httpConnection.setConnectTimeout(timeout);
            httpConnection.setReadTimeout(timeout);
        }
        // 默认headers
        httpConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        if (headerMap != null) {
            for (Map.Entry<String, String> mapEntry : headerMap.entrySet()) {
                httpConnection.setRequestProperty(mapEntry.getKey(), mapEntry.getValue());
            }
        }
        httpConnection.setRequestProperty("Content-Length", String.valueOf(data.length()));
        httpConnection.setRequestProperty("Accept-Charset", receiveEncoding);
        // 发送 post 必须
        httpConnection.setDoOutput(true);
        httpConnection.setDoInput(true);
        // 输出参数
        BufferedWriter outputBufferedWriter =
            new BufferedWriter(new OutputStreamWriter(httpConnection.getOutputStream(), sendEncoding));
        outputBufferedWriter.write(data);
        outputBufferedWriter.flush();
        outputBufferedWriter.close();
        // 输入内容
        BufferedReader inputBufferedReader = new BufferedReader(new InputStreamReader(
            httpConnection.getResponseCode() == 200 ? httpConnection.getInputStream() : httpConnection.getErrorStream(),
            receiveEncoding));
        StringBuilder sb = new StringBuilder();
        String readLine = null;
        while ((readLine = inputBufferedReader.readLine()) != null) {
            sb.append(readLine);
            // sb.append("\r\n");
        }
        inputBufferedReader.close();
        httpConnection.disconnect();
        // 计时结束
        stopWatch.stop();
        Long pastTime = stopWatch.getLastTaskTimeMillis();
        if (pastTime > 100) {
            logger.warn(formatLogContent(url, "", "request tired - httpPost, " + pastTime + "ms"));
        }

        logger.debug("HTTP POST 请求结束，响应内容：{}", sb.toString());
        return sb.toString();
    }

    /**
     * 检查是否包含特殊字符
     *
     * @param content
     * @return
     */
    public static boolean isSpecialChar(String content) {
        String pattern =
            "^[\u4e00-\u9fa5A-Za-z0-9\u0000-\u00FF\uFF00-\uFFFF　———……》、『 【 € ■ ○ ◆\"\"：；。，！…—·ˉˇ¨〃｜｀＇∶‖‘’〔〕〈〉《》「」『』．〖〗【】（）"
                + ((char)8220) + "" + ((char)8221) + "［］｛｝々～/？《、]+$";
        return !content.matches(pattern);
    }

    /**
     * 将值转换为整数 转换失败使用默认值
     *
     * @param value
     * @param defaultValue
     * @return
     */
    public static Integer valueOfInteger(String value, Integer defaultValue) {

        try {
            if (value == null || !value.matches("\\d+")) {
                return defaultValue;
            }
            return Z.valueOfInteger(value);
        } catch (Exception e) {
            logger.error("valueOfInteger error, value:{}, defaultValue:{}", value, defaultValue);
            return defaultValue;
        }
    }

    /**
     * 将值转换为整数
     *
     * @param value
     * @return
     */
    public static Integer valueOfInteger(String value) {
        return Integer.valueOf(value);
    }

    /**
     * Map转key：value
     *
     * @param map
     * @return
     */
    public static String mapConvertParams(Map<String, String> map) {
        StringBuffer sb = new StringBuffer();
        if (map == null) {
            return sb.toString();
        }
        for (Map.Entry<String, String> entry : map.entrySet()) {
            sb.append("&").append(entry.getKey()).append("=").append(Z.safeURLEncode(entry.getValue()));
        }
        return sb.substring(1);
    }

    /**
     * 格式化日期
     *
     * @param date
     * @return
     */
    public static String formatDate(Date date) {
        return defaultDateFormat.format(date);
    }

    /**
     * 转换时间
     *
     * @param date
     * @return
     */

    public static Optional<Date> convertDate(String date) {
        try {
            return Optional.ofNullable(defaultDateFormat.parse(date));
        } catch (ParseException e) {
            logger.error("转换时间发生异常，errMsg：{}，date：{}", e.getMessage(), date, e);
            return Optional.empty();
        }
    }

    public static Optional<Date> convertDate(String date, String pattern) {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat(pattern);

            return Optional.ofNullable(dateFormat.parse(date));
        } catch (ParseException e) {
            logger.error("转换时间发生异常，errMsg：{}，date：{}", e.getMessage(), date, e);
            return Optional.empty();
        }
    }

    /**
     * 获取请求响应流
     *
     * @param url
     * @param timeout
     * @return
     * @throws IOException
     */
    public static InputStream httpGetInputStream(String url, Integer timeout) throws IOException {

        URL httpUrl = new URL(url);
        HttpURLConnection httpConnection = (HttpURLConnection)httpUrl.openConnection();
        if (timeout > 0) {
            httpConnection.setConnectTimeout(timeout);
            httpConnection.setReadTimeout(timeout);
        }
        httpConnection.setRequestMethod("GET");

        InputStream inputStream = httpConnection.getInputStream();

        ByteArrayOutputStream baos = new ByteArrayOutputStream();

        byte[] buffer = new byte[1024];
        int len;
        while ((len = inputStream.read(buffer)) > -1) {
            baos.write(buffer, 0, len);
        }
        baos.flush();

        httpConnection.disconnect();

        return new ByteArrayInputStream(baos.toByteArray());

    }

    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    /**
     * 将集合根据指定长度进行分区 分区集合为原集合的子集合 修改原集合对象分区内的信息也会改变 具体可参看测试用例
     *
     * @param list
     *            原集合
     * @param size
     *            长度
     * @param <T>
     * @return 分区后的集合对象
     */
    public static <T> List<List<T>> partition(List<T> list, Integer size) {

        List<List<T>> lists = new ArrayList<>();

        for (int i = 0; i < list.size(); i += size) {
            // i + size 大于集合长度时截止位置为集合长度
            int end = Math.min(list.size(), i + size);
            lists.add(list.subList(i, end));
        }

        return lists;
    }

    /**
     * 安全的 URL 编码 发生异常返回空字符串
     *
     * @param content
     *            内容
     * @param encoding
     *            编码
     * @return
     */
    public static String safeURLEncode(String content, String encoding) {
        try {
            return URLEncoder.encode(content, encoding);
        } catch (UnsupportedEncodingException e) {
            return "";
        }
    }

    /**
     * 使用 UTF-8 编码 安全的 URL 编码 发生异常返回空字符串
     *
     * @param content
     *            内容
     * @return
     */
    public static String safeURLEncode(String content) {
        return safeURLEncode(content, "UTF-8");
    }

    /**
     * @param list
     *            使用分隔符连接集合
     * @param delimiter
     *            连接后的字符串
     * @return
     */
    public static <T> String joinString(List<T> list, String delimiter) {

        String result = list.stream().map(i -> i.toString()).collect(Collectors.joining(delimiter));

        return result;
    }

    /**
     * 字符串按指定字元打断成List<Long> 无效成员被忽略（永远不抛异常，默认按照逗号打断）
     *
     * @param submitid
     * @param splitChar
     * @return
     */
    public static List<Long> SplitToLongList(String submitid, char splitChar) {
        List<Long> list = new ArrayList<>();
        if (submitid.isEmpty()) {
            return list;
        }
        if (splitChar == '\0') {
            splitChar = ',';
        }
        String[] split = submitid.split(String.valueOf(splitChar));
        for (String s : split) {
            try {
                Long aLong = Long.valueOf(s);
                list.add(aLong);
            } catch (NumberFormatException e) {
                // e.printStackTrace();
            }
        }
        return list;
    }

    /**
     * 字符串按指定字元打断成List<String>
     *
     * @param msgid
     * @param c
     * @return
     */
    public static List<String> SplitToStringList(String msgid, char c) {
        List<String> list = new ArrayList<>();
        String[] split = msgid.split(String.valueOf(c));
        for (String s : split) {
            if(s.length()==0){
                //防止空字符问题
                continue;
            }
            list.add(s);
        }
        return list;
    }

    /**
     * 对字符串拆分并去重
     *
     * @param mobile
     * @param s
     * @return
     */
    public static List<String> SplitAndDistinct(String mobile, String s) {
        List<String> list = new ArrayList<>();
        String[] split = mobile.split(s);
        for (String s1 : split) {
            if (!list.contains(s1)) {
                list.add(s1);
            }
        }
        return list;
    }

    /**
     * 读取ip配置列表，支撑多种分隔符及ip段表示法
     *
     * @param ipConfigValue
     * @return
     */
    public static List<String> ReadIpConfig(String ipConfigValue) {
        List<String> list = new ArrayList<>();
        if (StringUtils.isBlank(ipConfigValue)) {
            return list;
        }
        String ipSplit =
            ipConfigValue.replace(" ", "").replace("  ", "").replace("\t", "").replace("\r\n", ",").replace("\n", ",");
        String[] split = ipSplit.split("[;,|]");
        List<String> arr = new ArrayList<>();
        for (String s : split) {
            if (s.length() > 0) {
                arr.add(s);
            }
        }
        for (String ip : arr) {
            if (ip.contains("-")) {
                list.addAll(readIpSection(ip));
            } else {
                list.add(ip);
            }
        }
        return list;
    }

    public static List<String> readIpSection(String ip) {
        List<String> list = new ArrayList<>();
        String[] arr = ip.split("\\.|\\,|\\-");
        if (arr.length == 5) {
            String network = arr[0] + "." + arr[1] + "." + arr[2] + ".";
            int ipStart = Integer.parseInt(arr[3]);
            int ipEnd = Integer.parseInt(arr[4]);
            for (int i = ipStart; i <= ipEnd; i++) {
                list.add(network + i);
            }
        }
        return list;
    }

    public static String objectToJson(Object obj) {
        String json = null;

        if (obj == null) {
            return null;
        }

        try {
            json = Z.objectMapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            logger.error(e.getMessage(), e);
        }

        return json;
    }

    public static <T> T jsonToObject(Class<T> objType, String json) {
        T obj = null;
        try {
            obj = Z.objectMapper.readValue(json, objType);
        } catch (IOException ie) {
            logger.error(ie.getMessage(), ie);
        } catch (Exception ex) {
            logger.error(ex.getMessage(), ex);
        }
        return obj;
    }

    /**
     * 模板的用这个
     */
    public static <T> T jsonToObject(final TypeReference<T> type, final String jsonPacket) {

        if (org.springframework.util.StringUtils.isEmpty(jsonPacket)) {
            return null;
        }

        T data = null;

        try {
            data = Z.objectMapper.readValue(jsonPacket, type);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

        return data;
    }

    public static long getCurrentTime() {
        return System.currentTimeMillis() / 1000;
    }

    public static long getRandom() {
        return (new Random(getCurrentTime())).nextInt(900000) + 100000;
    }

    static String md5(String password) {
        String encodeStr = DigestUtils.md5Hex(password + "SMmsEncryptKey");
        return encodeStr.toUpperCase();
    }

    public static String calculateSignature(String accountId, String password, long random, long timestamp,
        String mobile) {
        StringBuilder builder =
            new StringBuilder("AccountId=").append(accountId).append("&PhoneNos=").append(mobile).append("&Password=")
                .append(md5(password)).append("&Random=").append(random).append("&Timestamp=").append(timestamp);
        return sha256(builder.toString());
    }

    /**
     * SHA256 加密
     *
     * @param str
     * @return
     */
    private static String sha256(String str) {
        MessageDigest messageDigest;
        String encodestr = "";
        try {
            messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.update(str.getBytes("UTF-8"));
            encodestr = byte2Hex(messageDigest.digest());
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return encodestr;
    }

    /**
     * 将byte转为16进制
     *
     * @param bytes
     * @return
     */
    private static String byte2Hex(byte[] bytes) {
        StringBuffer buffer = new StringBuffer();
        String temp = null;
        for (int i = 0; i < bytes.length; i++) {
            temp = Integer.toHexString(bytes[i] & 0xFF);
            if (temp.length() == 1) {
                buffer.append("0");
            }
            buffer.append(temp);
        }
        return buffer.toString();
    }

    /**
     * 获取精确到秒的时间戳
     *
     * @param date
     * @return
     */
    public static int getSecondTimestamp(Date date) {
        if (null == date) {
            return 0;
        }
        String timestamp = String.valueOf(date.getTime());
        int length = timestamp.length();
        if (length > 3) {
            return Integer.valueOf(timestamp.substring(0, length - 3));
        } else {
            return 0;
        }
    }



    public static void main(String[] args) throws Exception {

    }

    public static String dealDateFormat(String oldDate) {
        Date date1 = null;
        DateFormat df2 = null;
        try {
            oldDate = oldDate.replace("Z", " UTC");
            DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
            Date date = df.parse(oldDate);
            SimpleDateFormat df1 = new SimpleDateFormat("EEE MMM dd HH:mm:ss Z yyyy", Locale.UK);
            date1 = df1.parse(date.toString());
            df2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        } catch (ParseException e) {

            e.printStackTrace();
        }
        return df2.format(date1);
    }

    public static String Base64Encode(String message) {
        /*String encode = "";
        try {
            encode = URLEncoder.encode(message, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        byte[] bytes = encode.getBytes();
        return Base64.getEncoder().encodeToString(bytes);*/
        byte[] utf8s = null;
        try {
            utf8s = message.getBytes("utf8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return Base64.getEncoder().encodeToString(utf8s);
    }


}