package com.cool.bang.modules.business.util;

import com.thoughtworks.xstream.XStream;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WeixinUtil {

    /**
     * 验证URL程序
     * @param token	在微信公众号中设置的TOKEN
     * @param timestamp	通过request获取的参数1
     * @param nonce	通过request获取的参数2
     * @param signature	通过request获取的参数3
     * @return
     */
    public static boolean check(String token, String timestamp, String nonce, String signature) {
        // 1）将token、timestamp、nonce三个参数进行字典序排序
        String[] strs = new String[]{ token, timestamp, nonce };
        Arrays.sort(strs);
        // 2）将三个参数字符串拼接成一个字符串进行sha1加密
        String str = strs[0]+strs[1]+strs[2];
        String jm = sha1(str);
        // 3）开发者获得加密后的字符串可与signature对比，标识该请求来源于微信
        return jm.equalsIgnoreCase(signature);
    }


    /**
     * 字符串sha1加密
     * @param src 待加密字符串
     * @return
     */
    private static String sha1(String src){
        try {
            //获取一个加密对象
            MessageDigest md = MessageDigest.getInstance("sha1");
            //加密
            byte[] diges = md.digest(src.getBytes());
            char[] chars = {'0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'};
            StringBuffer sb = new StringBuffer();
            //处理加密结果
            for(byte b:diges){
                sb.append(chars[(b>>4)&15]);
                sb.append(chars[b&15]);
            }
            return sb.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 解析xml数据包
     * @param is
     * @return
     */
    @SuppressWarnings("unchecked")
    public static Map<String, String> parseRequest(InputStream is){
        Map<String,String> map = new HashMap<>();
        SAXReader reader = new SAXReader();
        try {
            //读取输入流，获取文档对象  （把流放到Doc对象）
            Document document = reader.read(is);
            //根据文档对象获取根节点（获取xml根节点）
            Element root = document.getRootElement();
            //获取根节点的所有子节点
            List<Element> elements = root.elements();
            for(Element e:elements){
                map.put(e.getName(), e.getStringValue());
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }

        return map;
    }


    /**
     * 用于处理所有事件和消息的回复
     * 返回的是xml数据包
     * 微信公众号可以回复文本消息、图片消息等多种形式，该方法只处理了文本消息。
     */
    public static String getResponse(Map<String,String> requestMap, String appId, String redirectUrl){
        BaseMessgae msg = null;
        String msgType = requestMap.get("MsgType");
        switch ( msgType ){
            case "text": msg = dealTextMessage(requestMap, appId, redirectUrl); break;	//文本消息
            case "image": break;
            case "voice": break;
            case "video": break;
            case "shortvideo": break;
            case "location": break;
            case "link": break;
        }
        //把消息对象处理为xml数据包
        if( msg != null ){
            return beanToXml(msg);
        }
        return null;
    }


    /**
     * 处理文本消息
     * @param requestMap
     * @return
     */
    private static BaseMessgae dealTextMessage(Map<String, String> requestMap, String appId, String redirectUrl) {
        //在公众号中回复的内容，该处设置回复“1”显示测试连接
        String msg = requestMap.get("Content");
        if(msg.equals("1")){
            String url = "https://open.weixin.qq.com/connect/oauth2/authorize?";
            url += "appid="+appId;
            url += "&redirect_uri="+redirectUrl;
            url += "&response_type=code";
            url += "&scope=snsapi_userinfo#wechat_redirect";

            //回复文本全部内容：
            TextMessage tm = new TextMessage(requestMap, "点击<a href=\""+url+"\">这里</a>到主页面");
            return tm;
        }

        //回复其他内容时提示信息
        TextMessage tm = new TextMessage(requestMap, "你好，如要处理业务请回复以下选项</br>1:回复\"1\"<br>");
        return tm;
    }


    /**
     * 把消息对象处理为xml数据包
     *  只处理了文本消息
     * @param msg
     * @return
     */
    private static String beanToXml(BaseMessgae msg) {
        XStream xs = new XStream();
        //设置需要处理XStreamAlias("xml")注释的类
        xs.processAnnotations(TextMessage.class);
//		xs.processAnnotations(ImageMessage.class);
//		xs.processAnnotations(MusicMessage.class);
//		xs.processAnnotations(NewsMessage.class);
//		xs.processAnnotations(VideoMessage.class);
//		xs.processAnnotations(VoiceMessage.class);
        String xml = xs.toXML(msg);
        return xml;
    }



    public static String getResult(String url) {
        String result = "";
        BufferedReader in = null;
        try {
            URL urlObj = new URL(url);
            //开连接
            URLConnection connection = urlObj.openConnection();
            // 设置通用的请求属性
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            // 建立实际的连接
            connection.connect();
            in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8"));
            String line;
            while ((line = in.readLine()) != null) {
                result += line;
            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally {// 使用finally块来关闭输入流
            try {
                if (in != null) {
                    in.close();
                }
            } catch (Exception e2) {
                e2.printStackTrace();
            }

        }
        return result;
    }
}

