package org.example.api;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 短信网关接口(JSON)请求demo示例（JAVA）
 *
 * @author Administrator
 */
public class SmsDemo {
    private static final Logger logger = LoggerFactory.getLogger(SmsDemo.class);

    // 使用接口网关地址替换  http://sms.ue35.net/sms

    // 短信批量发送接口
    // http://sms.ue35.net/sms/api/sendMessageMass

    // 短信一对一发送接口
    // http://sms.ue35.net/sms/api/sendMessageOne

    // 回执状态获取接口
    // http://sms.ue35.net/sms/api/getReport

    // 上行回复获取接口
    // http://sms.ue35.net/sms/api/getUpstream

    // 查询余额接口
    // http://sms.ue35.net/sms/api/getBalance

    // 提交短信模板接口
    // http://sms.ue35.net/sms/api/createTemplate

    // 查询短信模板接口
    // http://sms.ue35.net/sms/api/queryTemplates

    // 报备签名接口
    // http://sms.ue35.net/sms/api/addSignature

    // 查询签名接口
    // http://sms.ue35.net/sms/api/querySignature

    public static void main(String[] args) {
        String userName = "xxx";// 帐号用户名
        String password = "xxx";// 帐号接口密码，跟登录密码不一样
        String address = "http://sms.ue35.net/sms";//接口网关地址 ，例如：http://127.0.0.1:8001/sms

//        sendMessageMass(userName, password, address); //批量发送
//        sendMessageOne(userName, password, address);//一对一
//        getReport(userName, password, address);//回执获取
//        getUpstream(userName, password, address);//上行获取
//        getBalance(userName, password, address);//查询余额
//        createTemplate(userName, password, address);//提交短信模板
//        queryTemplates(userName, password, address);//查询短信模板
//        addSignature(userName, password, address);//报备签名
//        querySignature(userName, password, address);//查询签名
    }

    /**
     * 帐号认证信息
     */
    public static JSONObject getSign(String userName, String password) {

        long timestamp = System.currentTimeMillis();// 13位时间戳,提交误差五分钟内有效

        // sign鉴权 md5(userName + timestamp + md5(password))
        String sign = md5(userName + timestamp + md5(password));

        JSONObject jsons = new JSONObject();
        jsons.put("userName", userName);
        jsons.put("timestamp", timestamp);
        jsons.put("sign", sign);

        return jsons;
    }

    /**
     * 短信批量发送接口
     *
     * @param userName
     * @param password
     * @param address
     */
    public static void sendMessageMass(String userName, String password, String address) {
        // 替换地址
        String url = "http://address:port/sms/api/sendMessageMass";
        url = url.replace("http://address:port/sms", address);

        String content = "【小小科技】您的验证码是123456";// 短信内容

        //发送手机号码，最大数量不得超过 10000 个号码，系统将自动去除重复号码
        List<String> phoneList = Arrays.asList("18278810211", "18278810212", "18278810213");

        // 拼接JSON
        JSONObject jsons = new JSONObject();
        jsons.put("content", content);

        //每次发送10000个号码
        int size = 10000;
        int length = phoneList.size();
        int index = length / size;
        int r = length % size;
        if (r > 0) {
            index += 1;
        }
        for (int i = 0; i < index; i++) {
            if (r > 0 && i == index - 1) {
                jsons.put("phoneList", phoneList.subList(i * size, length));
                jsons.putAll(getSign(userName, password));// 帐号认证信息，五分钟内有效，防止过期
                // 发送请求
                postUrl(url, jsons);
            } else {
                jsons.put("phoneList", phoneList.subList(i * size, (i + 1) * size));
                jsons.putAll(getSign(userName, password));// 帐号认证信息，五分钟内有效，防止过期
                postUrl(url, jsons);
            }
        }
    }

    /**
     * 短信一对一发送接口
     *
     * @param userName
     * @param password
     * @param address
     */
    public static void sendMessageOne(String userName, String password, String address) {
        // 替换地址
        String url = "http://address:port/sms/api/sendMessageOne";
        url = url.replace("http://address:port/sms", address);

        // 发送请求的数据
        JSONObject jsons = new JSONObject();

        // 数组形式，每个 JSON 对象包含短信内容和号码数据，最大 1000 个号码。
        int size = 1000;
        JSONArray messageList = new JSONArray();
        String content = "【一一科技】您的验证码是{%变量%}";
        String[][] list = new String[][]{{"18278810214", "123456"}, {"18278810215", "486512"}, {"18278810216", "889945"}};
        for (int i = 0; i < list.length; i++) {
            JSONObject msg = new JSONObject();
            msg.put("phone", list[i][0]);
            msg.put("content", content.replace("{%变量%}", list[i][1]));
            messageList.add(msg);
            if (i > 0 && (i + 1) % size == 0) {
                jsons.put("messageList", messageList);
                jsons.putAll(getSign(userName, password));// 帐号认证信息，五分钟内有效，防止过期
                // 发送请求
                postUrl(url, jsons);

                // 初始化空数据
                jsons = new JSONObject();
                messageList = new JSONArray();
            }
        }

        // 如果最后的还没发完，那在再处理一次
        if (messageList.size() > 0) {
            jsons.put("messageList", messageList);
            jsons.putAll(getSign(userName, password));// 帐号认证信息，五分钟内有效，防止过期
            // 发送请求
            postUrl(url, jsons);
        }
    }

    /**
     * 回执状态获取接口
     *
     * @param userName
     * @param password
     * @param address
     */
    public static void getReport(String userName, String password, String address) {
        //替换地址
        String url = "http://address:port/sms/api/getReport";
        url = url.replace("http://address:port/sms", address);

        postUrl(url, getSign(userName, password));// 帐号认证信息，五分钟内有效，防止过期);
    }

    /**
     * 上行回复获取接口
     *
     * @param userName
     * @param password
     * @param address
     */
    public static void getUpstream(String userName, String password, String address) {
        //替换地址
        String url = "http://address:port/sms/api/getUpstream";
        url = url.replace("http://address:port/sms", address);

        postUrl(url, getSign(userName, password));// 帐号认证信息，五分钟内有效，防止过期);
    }

    /**
     * 查询余额接口
     *
     * @param userName
     * @param password
     * @param address
     */
    public static void getBalance(String userName, String password, String address) {
        //替换地址
        String url = "http://address:port/sms/api/getBalance";
        url = url.replace("http://address:port/sms", address);

        postUrl(url, getSign(userName, password));// 帐号认证信息，五分钟内有效，防止过期);
    }

    /**
     * 提交短信模板接口
     *
     * @param userName
     * @param password
     * @param address
     */
    public static void createTemplate(String userName, String password, String address) {
        //替换地址
        String url = "http://address:port/sms/api/createTemplate";
        url = url.replace("http://address:port/sms", address);

        String content = "【小哈科技】验证码{%变量%}";

        JSONObject jsons = new JSONObject();
        jsons.putAll(getSign(userName, password));// 帐号认证信息，五分钟内有效，防止过期
        jsons.put("content", content);

        postUrl(url, jsons);
    }

    /**
     * 查询短信模板接口
     *
     * @param userName
     * @param password
     * @param address
     */
    public static void queryTemplates(String userName, String password, String address) {
        //替换地址
        String url = "http://address:port/sms/api/queryTemplates";
        url = url.replace("http://address:port/sms", address);

        postUrl(url, getSign(userName, password));// 帐号认证信息，五分钟内有效，防止过期);
    }

    /**
     * 报备签名接口
     *
     * @param userName
     * @param password
     * @param address
     */
    public static void addSignature(String userName, String password, String address) {
        //替换地址
        String url = "http://address:port/sms/api/addSignature";
        url = url.replace("http://address:port/sms", address);

        //短信签名，必须包含签名符号【】
        JSONArray signatureList = new JSONArray();
        signatureList.add("【嘻哈科技】");
        signatureList.add("【一一科技】");

        JSONObject jsons = new JSONObject();
        jsons.put("signatureList", signatureList);
        jsons.putAll(getSign(userName, password));// 帐号认证信息，五分钟内有效，防止过期

        postUrl(url, jsons);
    }

    /**
     * 查询签名接口
     *
     * @param userName
     * @param password
     * @param address
     */
    public static void querySignature(String userName, String password, String address) {
        //替换地址
        String url = "http://address:port/sms/api/querySignature";
        url = url.replace("http://address:port/sms", address);

        postUrl(url, getSign(userName, password));// 帐号认证信息，五分钟内有效，防止过期);
    }


    /**
     * md5加密(Byte)
     *
     * @param text
     * @return
     */
    private static String md5(String text) {
        if (text == null || "".equals(text.trim())) {
            throw new IllegalArgumentException("请输入要加密的内容");
        }
        String encryptText = null;
        try {
            MessageDigest m = MessageDigest.getInstance("md5");
            m.update(text.getBytes(StandardCharsets.UTF_8));
            byte[] arr = m.digest();
            StringBuffer sb = new StringBuffer(32);
            for (int i = 0; i < arr.length; ++i) {
                String hex = Integer.toHexString(arr[i] & 0xFF);
                if (hex.length() < 2) {
                    sb.append('0');
                }
                sb.append(hex);
            }
            return sb.toString();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return encryptText;
    }

    /**
     * 向指定地址发一个post请求，带着data数据
     *
     * @param jsonObject
     * @param url
     * @throws ParseException
     * @throws IOException
     */
    public static void postUrl(String url, JSONObject jsonObject) {
        String body = "";
        String encoding = "utf-8";
        //创建httpclient对象
        CloseableHttpClient client = HttpClients.createDefault();
        //创建post方式请求对象
        HttpPost httpPost = new HttpPost(url);
        //装填参数
        StringEntity s = new StringEntity(jsonObject.toString(), encoding);
        // 设置参数到请求对象中
        httpPost.setEntity(s);
        httpPost.setHeader("Content-type", "application/json");

        try {
            //执行请求操作，并拿到结果（同步阻塞）
            CloseableHttpResponse response = client.execute(httpPost);
            //获取结果实体
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                //按指定编码转换结果实体为String类型
                body = EntityUtils.toString(entity, encoding);
            }
            EntityUtils.consume(entity);
            //释放链接
            response.close();
        } catch (Exception e) {
            logger.info(e.getMessage(), e);
        }
        logger.info("请求地址： {}\n请求参数： {}\n请求结果： {}\n", url, jsonObject.toString(), body);
    }

}
