package com.dgtis.dorm.manager.db.util.wx;

import java.io.BufferedReader;
import java.io.InputStream;    
import java.io.InputStreamReader;    
import java.io.OutputStream;
import java.net.ConnectException;    
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.HttpsURLConnection;    
import javax.net.ssl.SSLContext;    
import javax.net.ssl.SSLSocketFactory;    
import javax.net.ssl.TrustManager;

import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import com.dgtis.dorm.manager.db.util.wx.entity.AccessToken;
import com.dgtis.dorm.manager.db.util.wx.entity.MessageData;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.slf4j.Logger;    
import org.slf4j.LoggerFactory;

/**  
 * weixin接口工具类  
 * @author ningshiyang
 */    
public class WeixinUtil {    
    private static Logger log = LoggerFactory.getLogger(WeixinUtil.class);    
    //创建静态map缓存  
    private static Map<String,AccessToken> weixinCacheToken = new HashMap<String, AccessToken>();
    
    /**  
     * 发起https请求并获取结果  
     * @param requestUrl 请求地址  
     * @param requestMethod 请求方式（GET、POST）  
     * @param outputStr 提交的数据  
     * @return JSONObject(通过JSONObject.get(key)的方式获取json对象的属性值)  
     */    
    public static JSONObject httpRequest(String requestUrl, String requestMethod, String outputStr) {    
        JSONObject jsonObject = null;    
        StringBuffer buffer = new StringBuffer();
        if(requestUrl != null && !"".equals(requestUrl)){
			try {
				// 创建SSLContext对象，并使用我们指定的信任管理器初始化
				TrustManager[] tm = { new MyX509TrustManager() };
				SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
				sslContext.init(null, tm, new java.security.SecureRandom());
				// 从上述SSLContext对象中得到SSLSocketFactory对象
				SSLSocketFactory ssf = sslContext.getSocketFactory();

				URL url = new URL(requestUrl);
				HttpsURLConnection httpUrlConn = (HttpsURLConnection) url.openConnection();
				httpUrlConn.setSSLSocketFactory(ssf);

				httpUrlConn.setDoOutput(true);
				httpUrlConn.setDoInput(true);
				httpUrlConn.setUseCaches(false);
				// 设置请求方式（GET/POST）
				httpUrlConn.setRequestMethod(requestMethod);

				if ("GET".equalsIgnoreCase(requestMethod))
					httpUrlConn.connect();

				// 当有数据需要提交时
				if (null != outputStr) {
					OutputStream outputStream = httpUrlConn.getOutputStream();
					// 注意编码格式，防止中文乱码
					outputStream.write(outputStr.getBytes("UTF-8"));
					outputStream.close();
				}

				// 将返回的输入流转换成字符串
				InputStream inputStream = httpUrlConn.getInputStream();
				InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");
				BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

				String str = null;
				while ((str = bufferedReader.readLine()) != null) {
					buffer.append(str);
				}
				bufferedReader.close();
				inputStreamReader.close();
				// 释放资源
				inputStream.close();
				inputStream = null;
				httpUrlConn.disconnect();
				jsonObject = JSONObject.fromObject(buffer.toString());
			} catch (ConnectException ce) {
				log.error("Weixin server connection timed out.");
			} catch (Exception e) {
				log.error("https request error:{}", e);
			}
		}

        return jsonObject;    
    }
    /**  
     * 获取access_token,调用接口凭证
     * @return  
     */    
    public static AccessToken getAccessToken() {   
		
		try {
			InputStream configFile = WeixinUtil.class.getClassLoader().getResourceAsStream("weixin.config.xml");
			SAXReader reader = new SAXReader();
			Document doc = reader.read(configFile);
			Element config = doc.getRootElement();
			String appid = config.elementTextTrim("appId");
			AccessToken accessToken = weixinCacheToken.get("token");  
			String requestUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential"
					+"&appid="+appid
					+"&secret="+config.elementTextTrim("secret");
			if(accessToken != null) {
				long time = accessToken.getTime();
				int expiresIn = accessToken.getExpiresIn();  
				long millions = new Long(expiresIn).longValue()*1000;
				long newDate = new Date().getTime();
				long rt = newDate - time;//获取当前时间跟存入时间的差值  
				if(rt > millions){  //判断时间是否已经过期  如果过期则重新请求， 否则不做处理
					JSONObject jsonObject = httpRequest(requestUrl, "GET", null);  //调用通用的https请求方法  
					// 如果请求成功    
					if (null != jsonObject) {
						try {
							if(jsonObject.containsKey("access_token") && jsonObject.containsKey("expires_in")){
								weixinCacheToken.remove("token");
								accessToken = new AccessToken();    
								accessToken.setToken(jsonObject.getString("access_token"));    
								accessToken.setExpiresIn(jsonObject.getInt("expires_in"));
								accessToken.setTime(new Date().getTime());
								weixinCacheToken.put("token", accessToken);
							} else 
								accessToken = null;    
						} catch (JSONException e) {    
							accessToken = null;    
							// 获取token失败    
							//log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
							log.error("获取taken失败");
						}    
					}    
				}
			} else {
				JSONObject jsonObject = httpRequest(requestUrl, "GET", null);  //调用通用的https请求方法  
				// 如果请求成功    
				if (null != jsonObject) {
					try {
						if(jsonObject.containsKey("access_token") && jsonObject.containsKey("expires_in")){
							accessToken = new AccessToken();    
							accessToken.setToken(jsonObject.getString("access_token"));    
							accessToken.setExpiresIn(jsonObject.getInt("expires_in"));
							accessToken.setTime(new Date().getTime());
							weixinCacheToken.put("token", accessToken);
						} else 
							accessToken = null;
					} catch (JSONException e) {    
						accessToken = null;    
						// 获取token失败    
						//log.error("获取token失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));    
						log.error("获取taken失败");
					}    
				}
			}
			return accessToken;    
		} catch (DocumentException e1) {
			e1.printStackTrace();
			return null;
		}
    	
    	
    }
    
    /**
     * 发送微信模板消息
     */
    public static String sendWXMessage(String accessToken, String openId, String formId, MessageData msgData){
		try {
			InputStream configFile = WeixinUtil.class.getClassLoader().getResourceAsStream("weixin.config.xml");
			SAXReader reader = new SAXReader();
			Document doc = reader.read(configFile);
			Element config = doc.getRootElement();
			String templateId = config.elementTextTrim("templateId");

			String sendMessage_url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN";
			String request_url = sendMessage_url.replace("ACCESS_TOKEN", accessToken);

			//System.out.println(request_url);

			String text = "{" +
					"\"touser\":\"" + openId + "\"," +
					"\"template_id\":\""+templateId+"\"," +
					"\"page\":\"pages/user/index/index\"," +
					"\"form_id\":\""+formId+"\"," +
					"\"data\":{" +
					"\"keyword1\":{\"value\":\""+msgData.getKeyword1()+"\",\"color\":\"#173177\"}," +
					"\"keyword2\":{\"value\":\""+msgData.getKeyword2()+"\",\"color\":\"#173177\"}," +
					"\"keyword3\":{\"value\":\""+msgData.getKeyword3()+"\",\"color\":\"#173177\"}," +
					"\"keyword4\":{\"value\":\""+msgData.getKeyword4()+"\",\"color\":\"#173177\"}" +
					"}" +
					"}";

			try {
				JSONObject jsonObject = httpRequest(request_url, "POST", text.toString());
				if (null != jsonObject) {
					try {
						//System.out.println(jsonObject.toString());
						if(jsonObject.containsKey("errcode") && jsonObject.containsKey("errmsg")){
							String errmsg = jsonObject.getString("errmsg");
							return errmsg;
						} else
							return "发送失败";
					} catch (JSONException e) {
						log.error("获取失败 errcode:{} errmsg:{}", jsonObject.getInt("errcode"), jsonObject.getString("errmsg"));
						return null;
					}
				} else
					return null;
			} catch (Exception e1) {
				log.error("获取失败");
				return null;
			}
		} catch (DocumentException e1) {
			e1.printStackTrace();
			return null;
		}
    }
    
}      