package com.live.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(com.live.client.OkHttpClient.class);

    Response response  ;
    int responseCode;
    JSONObject responseBody;
    HashMap<String, String> responseHeadsMap;
    RequestBody requestBody;
    Request request;
    Headers.Builder headerBuilder;
    String responseStr;
    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();
        // 以 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();
//        }
//    }

}




