package com.tofly.dc.util;

import cn.hutool.http.*;
import com.alibaba.fastjson.JSON;
import com.tofly.common.core.entity.ResultRespone;
import com.tofly.dc.comm.Constant;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.Map;

/**
 * http工具类
 *
 * @author zev
 * 2022/01/07
 * <p>
 * HttpClientUtil
 */
public class HttpClientUtil {

    /**
     * 编码格式,发送编码格式统一用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 ResultRespone<Object> 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 getHttpClientResult(execute,response);
    }

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

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

    /**
     * 发送post请求;带请求头和请求参数
     */
    public static ResultRespone<Object> 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 getHttpClientResult(execute,null);
    }

    /**
     * 发送post请求;json格式参数
     */
    public static ResultRespone<Object> 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 getHttpClientResult(execute,null);
    }


    /**
     * 发送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 {
        ResultRespone respone = new ResultRespone();
        String contentType = execute.header("content-type");
        if(contentType.contains(ContentType.JSON.getValue()) || contentType.contains(ContentType.MULTIPART.getValue()) || contentType.contains(ContentType.FORM_URLENCODED.getValue())){
            respone = JSON.parseObject(execute.body(), ResultRespone.class);
        }else {
            if(null!=response){
                ServletOutputStream outputStream = response.getOutputStream();
                InputStream inputStream = execute.bodyStream();
                // 设置响应编码
                response.setCharacterEncoding("UTF-8");
                response.setContentType("application/x-download");

                byte[] buffer = new byte[1024];
                int i = -1;
                while ((i = inputStream.read(buffer)) != -1) {
                    outputStream.write(buffer, 0, i);
                }
                outputStream.flush();
            }

        }

        return respone;
    }
}

