package org.mp.api.core.common;

import com.cftech.core.util.FileUtils;
import net.sf.json.JSONObject;
import org.mp.api.core.exception.WexinReqException;
import org.mp.api.wxbase.wxmedia.model.WxMediaForMaterial;
import org.mp.api.wxbase.wxmedia.model.WxMediaForMaterialResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

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.ConnectException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;

/**
 * 
 * @author xiaoqingfeng
 * 微信url请求公用方法
 * @
 */
public class WxstoreUtils {
	private static Logger logger = LoggerFactory.getLogger(WxstoreUtils.class);

	public static JSONObject httpRequest(String requestUrl,
			String requestMethod, String outputStr) {
		logger.debug("*********HTTPREQUEST START********");
		logger.debug("*********requestUrl is "+
				requestUrl+" END AND requestMethod IS"
				+requestMethod + " END AND  outputStr" 
				+outputStr +" END ********");
		JSONObject jsonObject = null;
		StringBuffer buffer = new StringBuffer();
		try {
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new SecureRandom());

			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);

			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());
			if (jsonObject.containsKey("errcode") && jsonObject.getInt("errcode") != 0) {
				logger.debug("********* ERROR********{}",buffer.toString());
				logger.debug("*********HTTPREQUEST END********");
				throw new WexinReqException("httpRequest Method！errcode="
						+ jsonObject.getString("errcode") + ",errmsg = "
						+ jsonObject.getString("errmsg"));
			} else {
				logger.debug("********* SUCCESS END********");
			}
		} catch (ConnectException ce) {
			System.out.println("Weixin server connection timed out.");
		} catch (Exception e) {
			System.out.println("https request error:{}" + e.getMessage());
		}
		return jsonObject;
	}

	public static JSONObject httpRequest2(String requestUrl,
			String requestMethod, byte[] outputStr) {
		JSONObject jsonObject = null;
		StringBuffer buffer = new StringBuffer();
		try {
			TrustManager[] tm = { new MyX509TrustManager() };
			SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, tm, new SecureRandom());

			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);

			httpUrlConn.setRequestMethod(requestMethod);

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

			if (null != outputStr) {
				OutputStream outputStream = httpUrlConn.getOutputStream();

				outputStream.write(outputStr);
				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) {
			System.out.print("Weixin server connection timed out.");
		} catch (Exception e) {
			System.out.print("https request error:{}" + e.getMessage());
		}
		return jsonObject;
	}

	public static void saveHttpImage(String requestUrl, String requestMethod,
			String outputStr, File target) {
		try {
			URL url = new URL(requestUrl);

			HttpURLConnection conn = (HttpURLConnection) url.openConnection();

			conn.setRequestMethod(requestMethod);

			conn.setConnectTimeout(5000);

			InputStream inStream = conn.getInputStream();

			byte[] data = readInputStream(inStream);

			FileOutputStream outStream = new FileOutputStream(target);

			outStream.write(data);

			outStream.close();
		} catch (Exception e) {
		}
	}

	public static String encode(byte[] bstr) {
		return new BASE64Encoder().encode(bstr);
	}

	public static byte[] decode(String str) {
		byte[] bt = null;
		try {
			BASE64Decoder decoder = new BASE64Decoder();
			bt = decoder.decodeBuffer(str);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return bt;
	}

	public static byte[] readInputStream(InputStream inStream) throws Exception {
		ByteArrayOutputStream outstream = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = -1;
		while ((len = inStream.read(buffer)) != -1) {
			outstream.write(buffer, 0, len);
		}
		outstream.close();
		inStream.close();

		return outstream.toByteArray();
	}
	

	/**
	 * 上传多媒体文件到微信公众平台
	 *
	 * @param requestUrl
	 * 
	 * @param file
	 *            文件
	 * @param content_type
	 *            文件类型
	 * @return 返回的字符串
	 * @throws Exception
	 */
	public static JSONObject uploadMediaFile(String requestUrl, File file,
			String content_type,String fileName) {
		System.out.println("requestUrl:"+requestUrl);
		System.out.println("file:"+file);
		System.out.println("content_type:"+content_type);
		System.out.println("fileName:"+fileName);
		JSONObject jsonObject = null;
		StringBuffer bufferStr = new StringBuffer();
		String end = "\r\n";
		String twoHyphens = "--"; // 用于拼接
		String boundary = "*****"; // 用于拼接 可自定义
		URL submit = null;
		DataOutputStream dos = null;
		// FileInputStream fis = null;
		BufferedInputStream bufin = null;
		BufferedReader bufferedReader = null;
		try {
			submit = new URL(requestUrl);
			HttpURLConnection conn = (HttpURLConnection) submit
					.openConnection();
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.setUseCaches(false);

			conn.setRequestMethod("POST");
			conn.setRequestProperty("Connection", "Keep-Alive");
			conn.setRequestProperty("Content-Type",
					"multipart/form-data;boundary=" + boundary);

			// 获取输出流对象，准备上传文件
			dos = new DataOutputStream(conn.getOutputStream());
			dos.writeBytes(twoHyphens + boundary + end);
			dos.writeBytes("Content-Disposition: form-data; name=\"" + file
					+ "\";filename=\"" + file.getName() + ";Content-Type=\""
					+ content_type + end);
//			dos.writeBytes("Content-Disposition: form-data; name=\"file\";filename=\"" + fileName + ";Content-Type=\""
//					+ content_type + end);
			dos.writeBytes(end);
			// 对文件进行传输
			bufin = new BufferedInputStream(new FileInputStream(file));
			byte[] buffer = new byte[8192]; // 8k
			int count = 0;
			while ((count = bufin.read(buffer)) != -1) {
				dos.write(buffer, 0, count);
			}

			bufin.close(); // 关闭文件流

			dos.writeBytes(end);
			dos.writeBytes(twoHyphens + boundary + twoHyphens + end);
			dos.flush();

			// 读取URL链接返回字符串
			InputStream inputStream = conn.getInputStream();
			InputStreamReader inputStreamReader = new InputStreamReader(
					inputStream, "utf-8");
			bufferedReader = new BufferedReader(inputStreamReader);

			String str = null;
			while ((str = bufferedReader.readLine()) != null) {
				bufferStr.append(str);
			}

			jsonObject = JSONObject.fromObject(bufferStr.toString());
			// System.out.println("-------------读取URL链接返回字符串--------------" +
			// bufferStr.toString());

		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("与服务器连接发生异常错误:" + e.toString());
			System.out.println("连接地址是:" + requestUrl);
			// throw new Exception("微信服务器连接错误！" + e.toString());
		} finally {

			try {
				if (dos != null) {
					dos.close();
				}
				if (bufferedReader != null) {
					bufferedReader.close();
				}

			} catch (Exception e2) {

			}
		}
		// 获取到返回Json请自行根据返回码获取相应的结果
		return jsonObject;
	}
	
	
	/**
	 * 2016-11-28 lisw add 上传其他类型永久素材到微信公众平台
	 * 
	 * @param fileName
	 *            文件名
	 * @param accessToken
	 * @param stream
	 *            文件流
	 * @param title
	 *            上传类型为video的参数
	 * @param introduction
	 *            上传类型为video的参数
	 * @param type
	 *            分别有图片（image）、语音（voice）、视频（video）和缩略图（thumb）
	 */
	public static WxMediaForMaterialResponse uploadPermanentMedia(String urls,WxMediaForMaterial wxMedia) {
		WxMediaForMaterialResponse mediaResource = null;
		try {
			// 这块是用来处理如果上传的类型是video的类型的
			// 拼装请求地址
			URL url = new URL(urls);
			String result = null;
			/**
			 * 你们需要在这里根据文件后缀suffix将type的值设置成对应的mime类型的值
			 */
			HttpURLConnection con = (HttpURLConnection) url.openConnection();
			con.setRequestMethod("POST"); // 以Post方式提交表单，默认get方式
			con.setDoInput(true);
			con.setDoOutput(true);
			con.setUseCaches(false); // post方式不能使用缓存
			// 设置请求头信息
			con.setRequestProperty("Connection", "Keep-Alive");
			con.setRequestProperty("Charset", "UTF-8");

			// 设置边界,这里的boundary是http协议里面的分割符，不懂的可惜百度(http 协议
			// boundary)，这里boundary 可以是任意的值(111,2222)都行
			String BOUNDARY = "----------" + System.currentTimeMillis();
			con.setRequestProperty("Content-Type",
					"multipart/form-data; boundary=" + BOUNDARY);
			StringBuilder sb = new StringBuilder();
			// 这块是post提交type的值也就是文件对应的mime类型值
			sb.append("--"); // 必须多两道线
			sb.append(BOUNDARY);
			sb.append("\r\n");
			sb.append(BOUNDARY);
			// 这里是media参数相关的信息，这里是否能分开下我没有试，感兴趣的可以试试
			sb.append("Content-Disposition: form-data;name=\"media\";filename=\""
					+ wxMedia.getFileName() + "\" \r\n");
			sb.append("Content-Type:application/octet-stream\r\n\r\n");
			System.out.println(sb.toString());
			byte[] head = sb.toString().getBytes("utf-8");
			// 获得输出流
			OutputStream out = new DataOutputStream(con.getOutputStream());
			// 输出表头
			out.write(head);
			// 文件正文部分
			// 把文件已流文件的方式 推入到url中
			DataInputStream in = new DataInputStream(wxMedia.getInputStream());
			int bytes = 0;
			byte[] bufferOut = new byte[1024];
			while ((bytes = in.read(bufferOut)) != -1) {
				out.write(bufferOut, 0, bytes);
			}
			in.close();
			// 结尾部分，这里结尾表示整体的参数的结尾，结尾要用"--"作为结束，这些都是http协议的规定
			byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线
			out.write(foot);
			out.flush();
			out.close();
			StringBuffer buffer = new StringBuffer();
			BufferedReader reader = null;
			// 定义BufferedReader输入流来读取URL的响应
			reader = new BufferedReader(new InputStreamReader(
					con.getInputStream()));
			String line = null;
			while ((line = reader.readLine()) != null) {
				buffer.append(line);
			}
			if (result == null) {
				result = buffer.toString();
			}
			// 使用JSON-lib解析返回结果
			JSONObject jsonObject = JSONObject.fromObject(result);
			if (jsonObject.get("errcode") != null) {
				logger.info(jsonObject.toString());
				return null;
			}
			mediaResource = new WxMediaForMaterialResponse();
			if ("thumb".equals(wxMedia.getType())) {
				mediaResource.setThumb_media_id(jsonObject.get("thumb_media_id").toString());
	        } else {
	        	mediaResource.setMedia_id(jsonObject.get("media_id").toString());
	        }
			if(jsonObject.containsKey("url")){
				mediaResource.setUrl(jsonObject.get("url").toString());
			}
			System.out.println("json:" + jsonObject.toString());
		} catch (IOException e) {
			e.printStackTrace();
		} finally {

		}
		return mediaResource;
	}
	
	
	/**
	 * 上传图片到微信公众平台
	 * @param args
	 * @throws FileNotFoundException
	 */
	public static JSONObject uploadImg(String urls,InputStream stream,String fileName){
		JSONObject jsonObject = new JSONObject();
		try {
			// 这块是用来处理如果上传的类型是video的类型的
			// 拼装请求地址
			URL url = new URL(urls);
			String result = null;
			HttpURLConnection con = (HttpURLConnection) url.openConnection();
			con.setRequestMethod("POST"); // 以Post方式提交表单，默认get方式
			con.setDoInput(true);
			con.setDoOutput(true);
			con.setUseCaches(false); // post方式不能使用缓存
			// 设置请求头信息
			con.setRequestProperty("Connection", "Keep-Alive");
			con.setRequestProperty("Charset", "UTF-8");

			// 设置边界,这里的boundary是http协议里面的分割符，不懂的可惜百度(http 协议
			// boundary)，这里boundary 可以是任意的值(111,2222)都行
			String BOUNDARY = "----------" + System.currentTimeMillis();
			con.setRequestProperty("Content-Type",
					"multipart/form-data; boundary=" + BOUNDARY);
			StringBuilder sb = new StringBuilder();
			// 这块是post提交type的值也就是文件对应的mime类型值
			sb.append("--"); // 必须多两道线
			sb.append(BOUNDARY);
			sb.append("\r\n");
			sb.append(BOUNDARY);
			// 这里是media参数相关的信息，这里是否能分开下我没有试，感兴趣的可以试试
			sb.append("Content-Disposition: form-data;name=\"media\";filename=\""
					+ fileName + "\" \r\n");
			sb.append("Content-Type:application/octet-stream\r\n\r\n");
			System.out.println(sb.toString());
			byte[] head = sb.toString().getBytes("utf-8");
			// 获得输出流
			OutputStream out = new DataOutputStream(con.getOutputStream());
			// 输出表头
			out.write(head);
			// 文件正文部分
			// 把文件已流文件的方式 推入到url中
			DataInputStream in = new DataInputStream(stream);
			int bytes = 0;
			byte[] bufferOut = new byte[1024];
			while ((bytes = in.read(bufferOut)) != -1) {
				out.write(bufferOut, 0, bytes);
			}
			in.close();
			// 结尾部分，这里结尾表示整体的参数的结尾，结尾要用"--"作为结束，这些都是http协议的规定
			byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");// 定义最后数据分隔线
			out.write(foot);
			out.flush();
			out.close();
			StringBuffer buffer = new StringBuffer();
			BufferedReader reader = null;
			// 定义BufferedReader输入流来读取URL的响应
			reader = new BufferedReader(new InputStreamReader(
					con.getInputStream()));
			String line = null;
			while ((line = reader.readLine()) != null) {
				buffer.append(line);
			}
			if (result == null) {
				result = buffer.toString();
			}
			// 使用JSON-lib解析返回结果
			jsonObject = JSONObject.fromObject(result);
			if (jsonObject.get("errcode") != null) {
				logger.info(jsonObject.toString());
				return null;
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {

		}
		return jsonObject;
	}
	
	
	public static void main(String[] args) throws FileNotFoundException {
		WxMediaForMaterial media = new WxMediaForMaterial();
		String imageUrl = "F:\\5687344c0ad9709.jpg";
		InputStream stream = FileUtils.getInputStream("http://weixin-10065849.file.myqcloud.com/aosmith/imagetext/imagetext1477560555434.jpg");
		File file  = new File(imageUrl);
		String fileName = file.getName();
		media.setFileName(fileName);
		media.setType("image");
		media.setInputStream(stream);
		String accessToken = "CIiTgMI3SRCzi9yAKccn_tr-xpgPr3tZGsBCRDPesqk-3fiSVtdohMEMAmRxIJK823PnAP6aQCPA0vjcY59NGuKC7FzFnMSE3UTGHvmyKJOjGFhm-GUlXKxR122efgSCTUEeAJAEFP";
		WxstoreUtils.uploadPermanentMedia("https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=M3F2rDb8LVe54EIaEk-uU-YhqTvQ1Yh2K6FjjX0LLSja9FszsNKzz9jAh732-Z-w7cYtnU3kD4XOX9Y0vYMCR-YL9DtKMpv5hSH1MgYsX2n-FkL2KRGrb6Jle7qCXpsUPPDcABABBP&type=image", media);
	}

}
