package com.yunniu.farming.util;

import org.apache.commons.codec.digest.DigestUtils;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.JDOMException;
import org.jdom2.input.SAXBuilder;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SignatureException;
import java.util.*;


public class PayUtil {
	/**       
	 * wxPay 微信小程序支付接口
	 *        
	 */       
	public static String sign(String text, String key, String input_charset) {
		text = text + "&key=" + key;           
		return DigestUtils.md5Hex(getContentBytes(text, input_charset));
	}      
	/**       
	* 签名字符串       
	*  @param text需要签名的字符串       
	* @param sign 签名结果       
	* @param key密钥       
	* @param input_charset 编码格式       
	* @return 签名结果       
	*/     
	public static boolean verify(String text, String sign, String key, String input_charset) {
		text = text + key;           
		String mysign = DigestUtils.md5Hex(getContentBytes(text, input_charset));
		if (mysign.equals(sign)) {              
			return true;           
		} else {               
			return false;           
		}       
	}       
/**       
* @param content       
* @param charset       
* @return       
* @throws SignatureException
* @throws UnsupportedEncodingException
*/      
	public static byte[] getContentBytes(String content, String charset) {
		if (charset == null || "".equals(charset)) {         
		return content.getBytes();           
		}         
		try {             
			return content.getBytes(charset);          
		} catch (UnsupportedEncodingException e) {
		throw new RuntimeException("MD5签名过程中出现错误,指定的编码集不对,您目前指定的编码集是:" + charset);
		}       
	}          
	private static boolean isValidChar(char ch) {       
		if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))    
			return true;           
		if ((ch >= 0x4e00 && ch <= 0x7fff) || (ch >= 0x8000 && ch <= 0x952f))        
			return true;
		// 简体中文汉字编码           
		return false;       
	}       
/**       
* 除去数组中的空值和签名参数     
  * @param sArray 签名参数组    
  * @return 去掉空值与签名参数后的新签名参数组     
  */       
	public static Map<String, String> paraFilter(Map<String, String> sArray) {
		Map<String, String> result = new HashMap<String, String>();
		if (sArray == null || sArray.size() <= 0) {      
			return result;          
		}           
		for (String key : sArray.keySet()) {
			String value = sArray.get(key);
			if (value == null || value.equals("") || key.equalsIgnoreCase("sign")       
                || key.equalsIgnoreCase("sign_type")) {             
					continue;              
			}               
			result.put(key, value);           
		}           return result;      
	}       
/**      
 * 把数组所有元素排序，并按照“参数=参数值”的模式用“&”字符拼接成字符串      
 * @param params 需要排序并参与字符拼接的参数组      
 * @return 拼接后字符串       
 */      
	public static String createLinkString(Map<String, String> params) {
		List<String> keys = new ArrayList<String>(params.keySet());
		Collections.sort(keys);
		String prestr = "";
		for (int i = 0; i < keys.size(); i++) {             
			String key = keys.get(i);
			String value = params.get(key);
			if (i == keys.size() - 1) {// 拼接时，不包括最后一个&字符               
				prestr = prestr + key + "=" + value;       
			} else {    
			prestr = prestr + key + "=" + value + "&";               
			}           
		}           
		return prestr;       
		}       
/**      
 *     
 * @param requestUrl请求地址   
 * @param requestMethod请求方法      
 * @param outputStr参数       
 */       
	public static String httpRequest(String requestUrl, String requestMethod, String outputStr){
		// 创建SSLContext          
		StringBuffer buffer = null;
		try{   	        
			URL url = new URL(requestUrl);
			HttpURLConnection conn = (HttpURLConnection) url.openConnection();
			conn.setRequestMethod(requestMethod);   	      
			conn.setDoOutput(true);   	     
			conn.setDoInput(true);   	    
			conn.connect();   	       
			//往服务器端写内容   	       
			if(null !=outputStr){   	         
				OutputStream os=conn.getOutputStream();
				os.write(outputStr.getBytes("utf-8"));   	   
				os.close();   	        
			}   	        
			// 读取服务器端返回的内容   	 
			InputStream is = conn.getInputStream();
			InputStreamReader isr = new InputStreamReader(is, "utf-8");
	        BufferedReader br = new BufferedReader(isr);
			buffer = new StringBuffer();
			String line = null;
			while ((line = br.readLine()) != null) {   	        	
				buffer.append(line);   	        
			}   
			br.close();       
		}catch(Exception e){
        e.printStackTrace();       
		}        
		return buffer.toString();    
	}        
	public static String urlEncodeUTF8(String source){
		String result=source;
		try {               
			result=java.net.URLEncoder.encode(source, "UTF-8");           
			} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block              
			e.printStackTrace();          
			}          
			return result;      
	} 	
/**	
 * 解析xml,返回第一级元素键值对。如果第一级元素有子节点，则此节点的值是子节点的xml数据。	
 * @param strxml	
 * @return	
 * @throws JDOMException	
 * @throws IOException
 */	
	public static Map<String, String> doXMLParse(String strxml) throws Exception {
		if(null == strxml || "".equals(strxml)) {	
			return null;	
		}				
		Map m = new HashMap();
		InputStream in = String2Inputstream(strxml);
		SAXBuilder builder = new SAXBuilder();		
		Document doc = builder.build(in);		
		Element root = doc.getRootElement();		
		List list = root.getChildren();
		Iterator it = list.iterator();
		while(it.hasNext()) {		
			Element e = (Element) it.next();		
			String k = e.getName();
			String v = "";
			List children = e.getChildren();
			if(children.isEmpty()) {			
				v = e.getTextNormalize();		
			} else {
				v = getChildrenText(children);		
			}						
			m.put(k, v);		
		}				
		//关闭流		
		in.close();				
		return m;	
	}	
	/**	 
	* 获取子结点的xml	 
	* @param children	 
	* @return String	 
	*/	
	public static String getChildrenText(List children) {
		StringBuffer sb = new StringBuffer();
		if(!children.isEmpty()) {	
			Iterator it = children.iterator();
			while(it.hasNext()) {		
				Element e = (Element) it.next();		
				String name = e.getName();
				String value = e.getTextNormalize();
				List list = e.getChildren();
				sb.append("<" + name + ">");			
				if(!list.isEmpty()) {				
					sb.append(getChildrenText(list));			
				}				
				sb.append(value);				
				sb.append("</" + name + ">");			
			}		
		}				
		return sb.toString();	
	}	
	public static InputStream String2Inputstream(String str) {
		return new ByteArrayInputStream(str.getBytes());
	}
	
	public static String GetMapToXML(Map<String,String> param){
        StringBuffer sb = new StringBuffer();
        sb.append("<xml>");  
        for (Map.Entry<String, String> entry : param.entrySet()) {
               sb.append("<"+ entry.getKey() +">");  
               sb.append(entry.getValue());  
               sb.append("</"+ entry.getKey() +">");  
       }    
        sb.append("</xml>");  
        return sb.toString();  
    } 
	
    /**
     * 验证回调签名
     * @return
     */
    public static boolean isTenpaySign(Map<String, String> map, String apikey) {
    	String characterEncoding="utf-8";
       String charset = "utf-8";
       String signFromAPIResponse = map.get("sign");
       if (signFromAPIResponse == null || signFromAPIResponse.equals("")) {
    	   //System.out.println("API返回的数据签名数据不存在，有可能被第三方篡改!!!"); 
    	   return false;
       }
       //System.out.println("服务器回包里面的签名是:" + signFromAPIResponse);
       //过滤空 设置 TreeMap
       SortedMap<String,String> packageParams = new TreeMap();
       
       for (String parameter : map.keySet()) {
    	   String parameterValue = map.get(parameter);
    	   String v = "";
    	   if (null != parameterValue) {
    		   v = parameterValue.trim();
    	   }
    	   packageParams.put(parameter, v);
       }
       
       StringBuffer sb = new StringBuffer();
       Set es = packageParams.entrySet();
       Iterator it = es.iterator();
       
       while(it.hasNext()) {
    	   Map.Entry entry = (Map.Entry)it.next();
    	   String k = (String)entry.getKey();
    	   String v = (String)entry.getValue();
    	   if(!"sign".equals(k) && null != v && !"".equals(v)) {
    		   sb.append(k + "=" + v + "&");
    	   }
       }
       sb.append("key=" + apikey);
       
     //将API返回的数据根据用签名算法进行计算新的签名，用来跟API返回的签名进行比较
     //算出签名
       String resultSign = "";
       String tobesign = sb.toString();
       
       if (null == charset || "".equals(charset)) {
    	   resultSign = MD5Util.MD5Encode(tobesign, characterEncoding).toUpperCase();
       }else{
    	   try{
    		   resultSign = MD5Util.MD5Encode(tobesign, characterEncoding).toUpperCase();
    	   }catch (Exception e) {
    		   resultSign = MD5Util.MD5Encode(tobesign, characterEncoding).toUpperCase();
    	   }
       }
       
       String tenpaySign = ((String)packageParams.get("sign")).toUpperCase();
       return tenpaySign.equals(resultSign);
    }

	/**
	 * 微信App支付创建链接字符串
	 * @param params
	 * @return
	 */
	public static String createLinkStringObject(Map<String, Object> params) {
		List<String> keys = new ArrayList<String>(params.keySet());
		Collections.sort(keys);
		String prestr = "";
		for (int i = 0; i < keys.size(); i++) {
			String key = keys.get(i);
			String value = params.get(key).toString();
			if (i == keys.size() - 1) {// 拼接时，不包括最后一个&字符
				prestr = prestr + key + "=" + value;
			} else {
				prestr = prestr + key + "=" + value + "&";
			}
		}
		return prestr;
	}
}

			



