package me.zhengjie.util;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.java.Log;
import me.zhengjie.utils.RedisUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.net.ssl.SSLContext;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author JiangHeJia
 * @version V1.0
 * @Title: shengneiUtil
 * @Package eladmin
 * @Description: 政务外网访问工具类
 * @date 2021/9/14 16:57
 */
@Log
public class shengneiUtil {

    @Autowired
    static RedisUtils redisUtils;

    /**
     * httpclient
     *
     * @return
     */
    public static CloseableHttpClient createSSLClientDefault() {
        try {
            HttpClientBuilder httpClientBuilder = HttpClientBuilder.create();
            //放开证书校验
            TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
            SSLContext sslContext =
                    org.apache.http.ssl.SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
            SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
            httpClientBuilder.setSSLSocketFactory(csf);
            return httpClientBuilder.build();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return HttpClients.createDefault();
    }

    /**
     * 获取token
     *
     * @return
     */
    public static void getToken(CloseableHttpClient httpClinet) {
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        //client_id
        nvps.add(new BasicNameValuePair("client_id", "fc5ef720-7fbc-17b1-71f2-0dffcae9ab33"));
        //client_secret
        nvps.add(new BasicNameValuePair("client_secret", "0b525da488a54ad8bf27ac3d857ed407"));
        nvps.add(new BasicNameValuePair("grant_type", "client_credentials"));
        nvps.add(new BasicNameValuePair("scope", "token"));
        String jsonStr = httpPostCoder(httpClinet, "https://gateway.zsj.jl.cegn.cn/oauth2/token", nvps); //post请求
        JSONObject parseObject = JSON.parseObject(jsonStr);
        if (!"".equals(parseObject.getString("access_token"))) {
            redisUtils.set("access_token", parseObject.getString("access_token"));
            log.info("获取token：" + redisUtils.get("access_token"));
        } else {
            log.info("返回token为空");
        }
    }

    /**
     * 非json参数方式POST提交
     *
     * @param
     * @param params
     * @return
     */

    public static String httpPostCoder(CloseableHttpClient httpclient, String uri, List<NameValuePair> params) {
        String result = "";
        try {
            HttpPost httpPost = new HttpPost(uri);
            httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded"); // 添加请求头
            httpPost.addHeader("Authorization-Type", "Oauth2"); // 添加请求头
            httpPost.addHeader("Service-Id", "4mw627"); // 添加请求头
            httpPost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
            HttpResponse response = httpclient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                InputStream instreams = entity.getContent();
                result = convertStreamToString(instreams);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 转化
     *
     * @param is
     * @return
     */

    public static String convertStreamToString(InputStream is) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuilder sb = new StringBuilder();

        String line = null;
        try {
            while ((line = reader.readLine()) != null) {
                sb.append(line + "\n");
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

    public static String doPost(String url, String param, String token, CloseableHttpClient httpClinet) {
        try {
            HttpPost post = new HttpPost(url);
            StringEntity entity = new StringEntity(param, "utf-8");
            entity.setContentEncoding("UTF-8");
            entity.setContentType("application/json");
            post.setEntity(entity);
            post.addHeader("Authorization-Type", "Oauth2");
            post.addHeader("Authorization", token);
            post.addHeader("Service-Id", "4mw627");
            HttpResponse response = httpClinet.execute(post);
            String rspBody = EntityUtils.toString(response.getEntity());
            return rspBody;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String doPosts(JSONObject obj) {
        CloseableHttpClient httpClinet = createSSLClientDefault();
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String da = sdf.format(date);
        String url = "https://gateway.zsj.jl.cegn.cn/api/visual/queryEBaseinfos";
        obj.put("appId", "9eb8158ca2654c149ed2e7ea6e5b6830");
        obj.put("version", "1.0.0");
        obj.put("charset", "2");
        obj.put("format", "JSON");
        obj.put("timestamp", da);
        log.info("发送内容" + obj);
//        查询redis中是否有token，没有获取一遍。
        if (Objects.equals(redisUtils.get("access_token"), null)) {
            getToken(httpClinet);
        }
        String doPost = doPost(url, obj.toString(), redisUtils.get("access_token").toString(), httpClinet);
        Map resultMap = JSONUtil.toMap(doPost);
//        返回状态码为400003(第三方接口查询失败)时，重新获取一遍token。
        if ("400003".equals(resultMap.get("code"))) {
            getToken(httpClinet);
        }
        return doPost;
    }
}
