package com.xiaomai.client;

import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.Assert;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSession;
import java.io.IOException;
import java.util.*;

/**
 * OkHttpClient
 * Created by adu on 2019/8/4 14:34
 */
public class OkHttpClient {

    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    public static okhttp3.OkHttpClient okHttpClient;
    public static Logger logger = LoggerFactory.getLogger(OkHttpClient.class);

    public Response response;
    public int responseCode;
    public JSONObject responseBody;
    public HashMap<String, String> responseHeadsMap;
    public RequestBody requestBody;
    public Request request;
    public Headers.Builder headerBuilder;
    public String responseStr;
    public Headers responseHeaderes;

    static {
        //ssl认证重写
        okHttpClient = new okhttp3.OkHttpClient.Builder().hostnameVerifier(
                new HostnameVerifier() {
                    public boolean verify(String s, SSLSession sslSession) {
                        return true;
                    }
                }
        ).build();
    }


    /**
     * json格式参数post请求
     * @param url
     * @param jsonDate
     * @param headers
     */
    /** 适用所有post的请求 **/
    /**
     * 发送json请求
     */
    public void doPostRequest(String url, String json, Map<String, String> headers) {
        try {
//            设置请求主体格式
            requestBody = RequestBody.create(JSON, json);
            //添加请求头
            headerBuilder = new Headers.Builder();
            // 以 Entry 添加消息头
            if (headers != null && headers.size() > 0) {
                Iterator iterator = headers.entrySet().iterator();
                while (iterator.hasNext()) {
                    Map.Entry entry = (Map.Entry) iterator.next();
                    headerBuilder.add((String) entry.getKey(), (String) entry.getValue());
                }
            }
            request = new Request.Builder()
                    .url(url)
                    .post(requestBody)
                    .headers(headerBuilder.build())
                    .build();
            response = okHttpClient.newCall(request).execute();
            responseCode = response.code();
            responseHeaderes = response.headers();
            responseStr = response.body().string();

        } catch (Exception e) {
            logger.error("okhttp3 执行 doPostRequest 异常 >> ex = {}", ExceptionUtils.getStackTrace(e));
        } finally {
            try {
                if (response != null) {
                    // response.close();
                }
            } catch (Exception e) {
                logger.error("okhttp3 执行 doPostRequest 异常  >> ex = {}", ExceptionUtils.getStackTrace(e));
            }
        }
    }


    public void doPostRequest(String url, IdentityHashMap<String, String> params,
                              Map<String, String> headers) {

        FormBody.Builder FormBodyBuilder = new FormBody.Builder();
        //添加参数
        if (params != null && params.keySet().size() > 0) {
            for (String key : params.keySet()) {
                FormBodyBuilder.add(key, String.valueOf(params.get(key)));
            }
        }
        headerBuilder = new Headers.Builder();
        // 以 Entry 添加消息头
        if (headers != null && headers.size() > 0) {
            Iterator iterator = headers.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                headerBuilder.add((String) entry.getKey(), (String) entry.getValue());
            }
        }

        request = new Request.Builder()
                .url(url)
                .post(FormBodyBuilder.build())
                .headers(headerBuilder.build())
                .build();
        try {
            response = okHttpClient.newCall(request).execute();
            responseCode = response.code();
            responseHeaderes = response.headers();
            responseStr = response.body().string();

            int status = response.code();
            Assert.assertEquals(status, 200);
        } catch (Exception e) {
            logger.error("okhttp3 执行失败 >> ex = {}", ExceptionUtils.getStackTrace(e));
        } finally {
            if (response != null) {
                // response.close();
            }
        }
    }

    /**
     * 发送Form 表单 post 请求
     *
     * @param url
     * @param paramsMap
     */
    public void doPostForForm(String url, IdentityHashMap<String, String> paramsMap, Map<String, String> headers) {

        FormBody.Builder FormBodyBuilder = new FormBody.Builder();
        //添加参数
        if (paramsMap != null && paramsMap.keySet().size() > 0) {
            for (String key : paramsMap.keySet()) {
                FormBodyBuilder.add(key, String.valueOf(paramsMap.get(key)));
            }
        }
        headerBuilder = new Headers.Builder();
        // 以 Entry 添加消息头
        if (headers != null && headers.size() > 0) {
            Iterator iterator = headers.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                headerBuilder.add((String) entry.getKey(), (String) entry.getValue());
            }
        }

        request = new Request.Builder()
                .url(url)
                .post(FormBodyBuilder.build())
                .headers(headerBuilder.build())
                .addHeader("contentType", "application/x-www-form-urlencoded; charset=UTF-8")
                .build();

        try {
            response = okHttpClient.newCall(request).execute();
            responseCode = response.code();
            responseHeaderes = response.headers();
            responseStr = response.body().string();
//          如果校验失败，会导致后续传参不执行
//            Assert.assertEquals(responseCode,200,responseCode+"：请求失败");

        } catch (Exception e) {
            logger.error("okhttp3 post error >> ex = {}", ExceptionUtils.getStackTrace(e));
        } finally {
            if (response != null) {
                // response.close();
            }
        }

    }


    /**
     * @param url     请求的url
     * @param queries 请求的参数，在浏览器？后面的数据，没有可以传null
     * @return
     */
    public void doGetRequest(String url, IdentityHashMap<String, String> queries, Map<String, String> headerParamsMap) {
        StringBuffer sb = new StringBuffer(url);
        if (queries != null && queries.keySet().size() > 0) {
            boolean firstFlag = true;
            Iterator iterator = queries.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry<String, Object>) iterator.next();
                if (firstFlag) {
                    sb.append("?" + entry.getKey() + "=" + entry.getValue());
                    firstFlag = false;
                } else {
                    sb.append("&" + entry.getKey() + "=" + entry.getValue());
                }
            }
        }

//        Headers.Builder headerBuilder = new Headers.Builder();
        headerBuilder = new Headers.Builder();
        // 以 Entry 添加消息头
        if (headerParamsMap != null && headerParamsMap.size() > 0) {
            Iterator iterator = headerParamsMap.entrySet().iterator();
            while (iterator.hasNext()) {
                Map.Entry entry = (Map.Entry) iterator.next();
                headerBuilder.add((String) entry.getKey(), (String) entry.getValue());
            }
        }

        request = new Request.Builder()
                .url(sb.toString())
                .headers(headerBuilder.build())
                .build();
        try {
            response = okHttpClient.newCall(request).execute();
            responseCode = response.code();
            responseHeaderes = response.headers();
            responseStr = response.toString();

//            Assert.assertEquals(responseCode,200,responseCode+"：请求失败");
        } catch (Exception e) {
            logger.error("okhttp3 put error >> ex = {}", ExceptionUtils.getStackTrace(e));
        } finally {
            if (response != null) {
                //  response.close();
            }
        }

    }


    /**
     * 以JSON格式获取到反馈的主体
     *
     * @return
     */
    public JSONObject getBodyInJSON() {
        if (responseStr != null) {
            try {
                //responseBody = com.alibaba.fastjson.JSON.parseObject(responseStr);
                responseBody = JSONObject.parseObject(responseStr);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("===============================================\n");
            System.out.println("This is your response body ==> \n" + responseBody);
            System.out.println("===============================================\n\n");

        } else {
            responseBody = null;
        }
        return responseBody;
    }

    /**
     * 以String格式获取到反馈的主体
     *
     * @return
     * @throws IOException
     */
    public String getBody() {

        System.out.println("===============================================\n");
        System.out.println("This is your response body ==> \n" + responseStr);
        System.out.println("===============================================\n\n");
        return responseStr;

    }

    /**
     * 以哈希图的方式获取到反馈头部
     *
     * @return
     */
    public HashMap<String, String> getHeaders() {
        responseHeadsMap = new HashMap<String, String>();
        if (null != responseHeaderes) {
            Set<String> names = responseHeaderes.names();
            for (String name : names) {
                responseHeadsMap.put(name, responseHeaderes.get(name));
            }
        }
        System.out.println("===============================================\n");
        System.out.println("This is your response header ==> \n" + responseHeadsMap);
        System.out.println("===============================================\n\n");
        return responseHeadsMap;
    }

    /**
     * 获取反馈状态码
     *
     * @return
     */
    public int getResponseCode() {
        System.out.println("===============================================\n");
        System.out.println("This is your response code ==> \n" + responseCode);
        System.out.println("===============================================\n\n");
        return responseCode;
    }

/**
 * okHttpClient 不需要手动关闭请求连接
 */
//    public void shutDownConnection(){
//        try {
//            okHttpClient.close();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//    }

}




