package com.tofly.scada.util;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.tofly.common.core.entity.ResultRespone;
import org.springframework.util.DigestUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Map;

/**
 * http工具类
 *
 * @author zev
 * 2022/01/07
 * <p>
 * HttpClientUtil
 */
public class HttpClientUtil {
    public static final String SYSTEM_SEPARATOR = "/";
    /**
     * 编码格式,发送编码格式统一用UTF-8
     */
    private static final String ENCODING = "UTF-8";

    /**
     * 设置连接超时时间,单位毫秒
     */
    private static final int CONNECT_TIMEOUT = 3 * 60 * 1000;

    /**
     * 请求响应超时时间,单位毫秒
     */
    private static final int SOCKET_TIMEOUT = 3 * 60 * 1000;

    /**
     * 发送get请求;带请求头和请求参数
     */
    public static String doGet(String url, Map<String, String> headers, Map<String, Object> params, HttpServletResponse response) throws Exception {
        //链式构建请求
        HttpResponse execute = HttpRequest.get(url)
                .addHeaders(headers)
                .form(params)
                .timeout(CONNECT_TIMEOUT)
                .execute();

        // 执行请求获取响应体并释放资源
        return execute.body();
    }

    public static ResultRespone<Object> doGetJoinId(String url, Map<String, String> headers, Map<String, Object> params, HttpServletResponse response) throws Exception {
        //链式构建请求
        String join = url + SYSTEM_SEPARATOR + params.get("id");
        HttpResponse execute = HttpRequest.get(join)
                .addHeaders(headers)
                .timeout(CONNECT_TIMEOUT)
                .execute();

        // 执行请求获取响应体并释放资源
        return getHttpClientResult(execute, response);
    }

    /**
     * 发送post请求;带请求头和请求参数
     */
    public static String doPost(String url, Map<String, String> headers, Map<String, Object> params) throws IOException {
        HttpResponse execute = HttpRequest.post(url)
                .addHeaders(headers)
                //表单内容
                .form(params)
                //超时，毫秒
                .timeout(CONNECT_TIMEOUT)
                .execute();

        // 执行请求获取响应体并释放资源
        return execute.body();
    }

    /**
     * 发送post请求;json格式参数
     */
    public static String doPostJson(String url, Map<String, String> headers, String json) throws IOException {
        HttpResponse execute = HttpRequest.post(url)
                .addHeaders(headers)
                .body(json)
                .timeout(CONNECT_TIMEOUT)
                .execute();

        // 执行请求获取响应体并释放资源
        return execute.body();
    }


    /**
     * 发送put请求;带请求头和请求参数
     */
    public static ResultRespone<Object> doPut(String url, Map<String, String> headers, Map<String, Object> params) throws IOException {
        HttpResponse execute = HttpRequest.put(url)
                .addHeaders(headers)
                //表单内容
                .form(params)
                //超时，毫秒
                .timeout(CONNECT_TIMEOUT)
                .execute();

        // 执行请求获取响应体并释放资源
        return getHttpClientResult(execute, null);
    }

    public static ResultRespone<Object> doPutJson(String url, Map<String, String> headers, String json) throws IOException {
        HttpResponse execute = HttpRequest.put(url)
                .addHeaders(headers)
                .body(json)
                .timeout(CONNECT_TIMEOUT)
                .execute();

        // 执行请求获取响应体并释放资源
        return getHttpClientResult(execute, null);
    }


    /**
     * 发送delete请求;带请求头
     */
    public static ResultRespone<Object> doDelete(String url, Map<String, String> headers, Map<String, Object> params) throws Exception {
        HttpResponse execute = HttpRequest.delete(url)
                .addHeaders(headers)
                //表单内容
                .form(params)
                //超时，毫秒
                .timeout(CONNECT_TIMEOUT)
                .execute();

        // 执行请求获取响应体并释放资源
        return getHttpClientResult(execute, null);
    }


//
//    /**
//     * 设置请求头
//     */
//    private static void packageHeader(Map<String, String> headers, HttpRequestBase httpMethod) {
//        if (!ObjectUtils.isEmpty(headers)) {
//            headers.forEach(httpMethod::setHeader);
//        }
//    }
//
//    /**
//     * 封装请求参数
//     */
//    private static void packageParam(Map<String, String> params, HttpEntityEnclosingRequestBase httpMethod) throws UnsupportedEncodingException {
//        if (!ObjectUtils.isEmpty(params)) {
//            List<NameValuePair> nameValuePairs = new ArrayList<>();
//            params.forEach((key, value) -> nameValuePairs.add(new BasicNameValuePair(key, value)));
//            httpMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs, ENCODING));
//        }
//    }
//
//    /**
//     * 封装请求参数为json格式
//     */
//    private static void packageJson(String json, HttpEntityEnclosingRequestBase httpMethod) {
//        if (!ObjectUtils.isEmpty(json)) {
//            StringEntity stringEntity = new StringEntity(json, ContentType.APPLICATION_JSON);
//            httpMethod.setEntity(stringEntity);
//        }
//    }

    /**
     * 执行请求获取响应体并释放资源
     */
    private static ResultRespone<Object> getHttpClientResult(HttpResponse execute, HttpServletResponse response) throws IOException {
        String body = execute.body();
        System.out.println(body);
        ResultRespone respone = JSON.parseObject(execute.body(), ResultRespone.class);
        return respone;
    }

    /**
     * MD5加密之方法二
     * @explain java实现
     * @param str
     *            待加密字符串
     * @return 16进制加密字符串
     */
    public static String encrypt2ToMD5(String str) {
        // 加密后的16进制字符串
        String hexStr = "";
        try {
            // 此 MessageDigest 类为应用程序提供信息摘要算法的功能
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            // 转换为MD5码
            byte[] digest = md5.digest(str.getBytes("utf-8"));
            hexStr = new BigInteger(1, digest).toString(16);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return hexStr;
    }


    /**
     * @param text
     * @return 传统的MD5加密方式，与客户端加密方法相同
     * @throws Exception
     */
    public static String TraditionMd5(String text) {
        //加密后的字符串
        byte[] bytes = text.getBytes(StandardCharsets.UTF_8);
        byte[] encodeStrByte= DigestUtils.md5Digest(bytes);
        String re=bytesToHexFun1(encodeStrByte);
        return re;
    }

    private static final char[] HEX_CHAR = {'0', '1', '2', '3', '4', '5',
            '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    /**
     * byte[]数组转16进制字符串
     * @param bytes
     * @return
     */
    public static String bytesToHexFun1(byte[] bytes) {
        // 一个byte为8位，可用两个十六进制位标识
        char[] buf = new char[bytes.length * 2];
        int a = 0;
        int index = 0;
        for(byte b : bytes) { // 使用除与取余进行转换
            if(b < 0) {
                a = 256 + b;
            } else {
                a = b;
            }

            buf[index++] = HEX_CHAR[a / 16];
            buf[index++] = HEX_CHAR[a % 16];
        }

        return new String(buf);
    }

}

