package com.template.common.utils;

import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * HttpsClient类
 * @author lujunjie
 * @date   2018/03/01
 */
public class HttpsClient {

    /**
     * GET请求方式
     */
    public static final String METHOD_GET = "GET";
    /**
     * POST请求方式
     */
    public static final String METHOD_POST = "POST";
    /**
     * 连接超时时间
     */
    private static Integer CONNECTION_TIMEOUT = WxConfig.connectionTimeout;
    /**
     * 请求超时时间
     */
    private static Integer READ_TIMEOUT = WxConfig.readTimeout;

    /**
     * 发起https请求
     * @param requestUrl 请求地址
     * @param requestMethod 请求方式（Get或者post）
     * @param postData 提交数据
     * @return JSONObject
     */
    public static JSONObject httpsRequestReturnJSONObject(String requestUrl, String requestMethod, String postData) throws Exception{
        JSONObject  jsonObject = JSONObject.parseObject(HttpsClient.httpsRequestReturnString(requestUrl,requestMethod,postData));
        System.out.println("jsonObjectDate:  " + jsonObject);
        return jsonObject;
    }


    /**
     * 发起https请求
     * @param requestUrl 请求地址
     * @param requestMethod 请求方式（Get或者post）
     * @param postData 提交数据
     * @return String
     */
    public static String httpsRequestReturnString(String requestUrl, String requestMethod, String postData) throws Exception{
        String response;
        HttpsURLConnection httpsUrlConnection = null;
        try{
            //创建https请求证书
            TrustManager[] tm={new MyX509TrustManager()};
            //创建SSLContext管理器对像，使用我们指定的信任管理器初始化
            SSLContext sslContext=SSLContext.getInstance("SSL","SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            SSLSocketFactory ssf=sslContext.getSocketFactory();

            // 创建URL对象
            URL url= new URL(requestUrl);
            // 创建HttpsURLConnection对象，并设置其SSLSocketFactory对象
            httpsUrlConnection=(HttpsURLConnection)url.openConnection();
            //设置ssl证书
            httpsUrlConnection.setSSLSocketFactory(ssf);

            //设置header信息
            httpsUrlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            //设置User-Agent信息
            httpsUrlConnection.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.146 Safari/537.36");
            //设置可接受信息
            httpsUrlConnection.setDoOutput(true);
            //设置可输入信息
            httpsUrlConnection.setDoInput(true);
            //不使用缓存
            httpsUrlConnection.setUseCaches(false);
            //设置请求方式（GET/POST）
            httpsUrlConnection.setRequestMethod(requestMethod);
            //设置连接超时时间
            if (CONNECTION_TIMEOUT > 0) {
                httpsUrlConnection.setConnectTimeout(CONNECTION_TIMEOUT);
            } else {
                //默认10秒超时
                httpsUrlConnection.setConnectTimeout(10000);
            }
            //设置请求超时
            if (READ_TIMEOUT > 0) {
                httpsUrlConnection.setReadTimeout(READ_TIMEOUT);
            } else {
                //默认10秒超时
                httpsUrlConnection.setReadTimeout(10000);
            }
            //设置编码
            httpsUrlConnection.setRequestProperty("Charsert", WxConstants.DEFAULT_CHARSET);

            //判断是否需要提交数据
            if(StringUtils.equals(requestMethod,HttpsClient.METHOD_POST) && StringUtils.isNotBlank(postData)){
                //讲参数转换为字节提交
                byte[] bytes = postData.getBytes(WxConstants.DEFAULT_CHARSET);
                //设置头信息
                httpsUrlConnection.setRequestProperty("Content-Length", Integer.toString(bytes.length));
                //开始连接
                httpsUrlConnection.connect();
                //防止中文乱码
                OutputStream outputStream=httpsUrlConnection.getOutputStream();
                outputStream.write(postData.getBytes(WxConstants.DEFAULT_CHARSET));
                outputStream.flush();
                outputStream.close();
            }else{
                //开始连接
                httpsUrlConnection.connect();
            }
            response = WxUtil.getStreamString(httpsUrlConnection.getInputStream());
        }catch (Exception e){
            throw new Exception();
        }finally {
            if (httpsUrlConnection != null) {
                // 关闭连接
                httpsUrlConnection.disconnect();
            }
        }
        return response;
    }


    public static String get(String url, Map<String, String> params){
        CloseableHttpClient httpClient = null;
        HttpGet httpGet = null;
        StringBuffer str = new StringBuffer("");
        try {
            httpClient = HttpClients.createDefault();
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(20000).setConnectTimeout(20000).build();
            String ps = "";
            for (String pKey : params.keySet()) {
                if(!"".equals(ps)){
                    ps = ps + "&";
                }
                ps = pKey+"="+params.get(pKey);
            }
            if(!"".equals(ps)){
                url = url + "?" + ps;
            }
            httpGet = new HttpGet(url);
            httpGet.setConfig(requestConfig);
            CloseableHttpResponse response = httpClient.execute(httpGet);
            HttpEntity httpEntity = response.getEntity();
            str.append(EntityUtils.toString(httpEntity,"utf-8"));
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                if(httpGet!=null){
                    httpGet.releaseConnection();
                }
                if(httpClient!=null){
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return str.toString();
    }

    public static String get(String strURL) throws Exception{

        URL url = new URL(strURL);
        HttpURLConnection httpConn = (HttpURLConnection)
                url.openConnection();
        httpConn.setRequestMethod("GET");
        httpConn.connect();
        System.out.println("bbb: "+httpConn.getResponseCode());
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                httpConn.getInputStream(),"utf-8"));
        String line;
        StringBuffer buffer = new StringBuffer();
        while ((line = reader.readLine()) != null) {
            buffer.append(line);
        }
        reader.close();
        httpConn.disconnect();

        return buffer.toString();
    }

    /**
     * 发送 post请求
     * @param
     * @param
     */
    public static String post(String url, Map<String, String> params){
        CloseableHttpClient httpClient = null;
        HttpPost httpPost = null;
        StringBuilder sb = new StringBuilder("");
        try {
            httpClient = HttpClients.createDefault();
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(20000).setConnectTimeout(20000).build();
            httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            List<NameValuePair> ps = new ArrayList<NameValuePair>();
            for (String pKey : params.keySet()) {
                ps.add(new BasicNameValuePair(pKey, params.get(pKey)));
            }
            httpPost.setEntity(new UrlEncodedFormEntity(ps));
            CloseableHttpResponse response = httpClient.execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            sb.append(EntityUtils.toString(httpEntity,"utf-8"));
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                if(httpPost!=null){
                    httpPost.releaseConnection();
                }
                if(httpClient!=null){
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sb.toString();
    }

    public static String postFile(String url, File file){

        CloseableHttpClient httpClient = null;
        HttpPost httpPost = null;
        StringBuilder sb = new StringBuilder("");
        try {
            MultipartEntityBuilder builder = MultipartEntityBuilder.create();
            builder.addBinaryBody("files", file, ContentType.DEFAULT_BINARY, file.getName());
            httpClient = HttpClients.createDefault();
            RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(20000).setConnectTimeout(20000).build();
            httpPost = new HttpPost(url);
            httpPost.setConfig(requestConfig);
            httpPost.setEntity(builder.build());
            CloseableHttpResponse response = httpClient.execute(httpPost);
            HttpEntity httpEntity = response.getEntity();
            sb.append(EntityUtils.toString(httpEntity,"utf-8"));
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }finally{
            try {
                if(httpPost!=null){
                    httpPost.releaseConnection();
                }
                if(httpClient!=null){
                    httpClient.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        JSONObject  jsonObject = JSONObject.parseObject(sb.toString());
        return jsonObject.get("data").toString();
    }

    //url表示请求链接，param表示json格式的请求参数		//自定义菜单创建访问方式
    public static String sendPost(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            URL realUrl = new URL(url);
            // 打开和URL之间的连接
            URLConnection conn = realUrl.openConnection();
            // 设置通用的请求属性 注意Authorization生成
            // conn.setRequestProperty("Content-Type",
            // "application/x-www-form-urlencoded");
            // 发送POST请求必须设置如下两行
            conn.setDoOutput(true);
            conn.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(),"utf-8"));
            // 发送请求参数
            out.print("&"+param);
            // flush输出流的缓冲
            out.flush();
            // 定义BufferedReader输入流来读取URL的响应
            in = new BufferedReader(
                    new InputStreamReader(conn.getInputStream(),"utf-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }
        } catch (Exception e) {
            System.out.println("发送 请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }


    //url表示请求链接，param表示json格式的请求参数		//自定义菜单创建访问方式
    public static String sendPost2(String url, String param) {
        PrintWriter out = null;
        BufferedReader in = null;
        String result = "";
        try {
            HttpsURLConnection httpsUrlConnection = null;
            //创建https请求证书
            TrustManager[] tm={new MyX509TrustManager()};
            //创建SSLContext管理器对像，使用我们指定的信任管理器初始化
            SSLContext sslContext=SSLContext.getInstance("SSL","SunJSSE");
            sslContext.init(null, tm, new java.security.SecureRandom());
            SSLSocketFactory ssf=sslContext.getSocketFactory();
            // 创建URL对象
            URL realUrl= new URL(url);
            // 创建HttpsURLConnection对象，并设置其SSLSocketFactory对象,
            // 打开和URL之间的连接
            httpsUrlConnection=(HttpsURLConnection)realUrl.openConnection();
            //设置ssl证书
            httpsUrlConnection.setSSLSocketFactory(ssf);
            // 设置通用的请求属性 注意Authorization生成
            // conn.setRequestProperty("Content-Type",
            // "application/x-www-form-urlencoded");
            // 发送POST请求必须设置如下两行
            httpsUrlConnection.setRequestMethod("POST");
            httpsUrlConnection.setDoOutput(true);
            httpsUrlConnection.setDoInput(true);
            // 获取URLConnection对象对应的输出流
            out = new PrintWriter(new OutputStreamWriter(httpsUrlConnection.getOutputStream(),"utf-8"));
            // 发送请求参数
            out.print("&"+param);
            // flush输出流的缓冲
            out.flush();
            if (httpsUrlConnection.getResponseCode()==200) {
                // 定义BufferedReader输入流来读取URL的响应
                in = new BufferedReader(
                        new InputStreamReader(httpsUrlConnection.getInputStream(), "utf-8"));
                String line;
                while ((line = in.readLine()) != null) {
                    result += line;
                }
            }else {
                result = "获取输入流异常！";
            }
        } catch (Exception e) {
            System.out.println("发送 请求出现异常！" + e);
            e.printStackTrace();
        }
        // 使用finally块来关闭输出流、输入流
        finally {
            try {
                if (out != null) {
                    out.close();
                }
                if (in != null) {
                    in.close();
                }
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
        return result;
    }

    public static String dateToStamp(String s) throws Exception {
        String res = "";
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = simpleDateFormat.parse(s);
        long time = date.getTime();
        res = String.valueOf(time);
        return res;
    }

    /*
     * 将时间戳转换为时间
     */
    public static String stampToDate(String s){
        String res;
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long lt = new Long(s);
        Date date = new Date(lt);
        res = simpleDateFormat.format(date);
        return res;
    }

    public static String sendJson(String request_url, JSONObject json) {
        OutputStreamWriter out = null;
        InputStream is = null;
        String result = "";
        try {
            URL url = new URL(request_url);// 创建连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestMethod("POST"); // 设置请求方式
            // 设置接收数据的格式
            connection.setRequestProperty("Accept", "application/json");
            // 设置发送数据的格式
            connection.setRequestProperty("Content-Type", "application/json");
            connection.connect();
            out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
            out.append(json.toString());
            out.flush();
            out.close();
            // 读取响应
            is = connection.getInputStream();
            int length = (int) connection.getContentLength();// 获取字节长度
            System.out.println(length);
            if (length != -1) {
                byte[] data = new byte[length];
                byte[] temp = new byte[512];
                int readLen = 0;
                int destPos = 0;
                while ((readLen = is.read(temp)) > 0) {
                    System.arraycopy(temp, 0, data, destPos, readLen);
                    destPos += readLen;
                }
                result = new String(data, "UTF-8"); // utf-8编码
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    /**
     * post请求
     * @param request_url
     * @param json
     * @return
     */
    public static String sendJson2(String request_url, JSONObject json) {
        OutputStreamWriter out = null;
        InputStream is = null;
        String result = "";
        try {
            URL url = new URL(request_url);// 创建连接
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestMethod("POST"); // 设置请求方式
            // 设置接收数据的格式
            connection.setRequestProperty("Accept", "application/json");
            // 设置发送数据的格式
            connection.setRequestProperty("Content-Type", "application/json");
            connection.connect();
            out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
            out.append(json.toString());
            out.flush();
            out.close();
            // 读取响应
            is = connection.getInputStream();
            BufferedReader in = new BufferedReader(new InputStreamReader(is));
            result = in.readLine();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;
    }

    public static void main(String[] args) throws Exception {
        JSONObject json = new JSONObject();
        json.put("buildCode", "5栋");
        json.put("currentAggr", "20");
        json.put("energyType", "2");
        json.put("updateTime", "2021-09-09 10:15:33");
        String msg = sendJson2("https://chtech.ncjti.edu.cn/bigdata-api/api/energy/energyDataUpload", json);
        System.out.println(msg);
    }
}
