package com.ym.mec.util.http;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import com.ym.mec.util.compress.ZipUtil;

public class HttpUtil {

	/**
	 * POST请求http url
	 * 
	 * @param url
	 *            URL
	 * @param parameterMap
	 *            请求参数
	 * @return 返回结果
	 * @throws IOException 
	 */
	public static String postForHttp(String url, Map<String, Object> parameterMap) throws IOException {
		String result = null;
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);
		try {
			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			if (parameterMap != null) {
				for (Entry<String, Object> entry : parameterMap.entrySet()) {
					String name = entry.getKey();
					String value = ConvertUtils.convert(entry.getValue());
					if (StringUtils.isNotEmpty(name)) {
						nameValuePairs.add(new BasicNameValuePair(name, value));
					}
				}
			}
			httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
			HttpResponse httpResponse = httpClient.execute(httpPost);
			HttpEntity httpEntity = httpResponse.getEntity();
			result = EntityUtils.toString(httpEntity, "UTF-8");
			EntityUtils.consume(httpEntity);
		} finally {
			httpPost.releaseConnection();
			httpClient.close();
		}
		return result;
	}

	/**
	 * POST请求https url
	 * 
	 * @param url
	 *            URL
	 * @param parameterMap
	 *            请求参数
	 * @return 返回结果
	 * @throws IOException 
	 * @throws NoSuchAlgorithmException 
	 * @throws KeyManagementException 
	 * @throws KeyStoreException 
	 */
	public static String postForHttps(String url, Map<String, Object> parameterMap) throws IOException, NoSuchAlgorithmException, KeyManagementException,
			KeyStoreException {
		String result = null;
		CloseableHttpClient httpClient = SimpleHttpsClient.getInstance();

		HttpPost httpPost = new HttpPost(url);
		try {
			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			if (parameterMap != null) {
				for (Entry<String, Object> entry : parameterMap.entrySet()) {
					String name = entry.getKey();
					String value = ConvertUtils.convert(entry.getValue());
					if (StringUtils.isNotEmpty(name)) {
						nameValuePairs.add(new BasicNameValuePair(name, value));
					}
				}
			}
			httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
			HttpResponse httpResponse = httpClient.execute(httpPost);
			HttpEntity httpEntity = httpResponse.getEntity();
			result = EntityUtils.toString(httpEntity, "UTF-8");
			EntityUtils.consume(httpEntity);
		} finally {
			httpPost.releaseConnection();
			httpClient.close();
		}
		return result;
	}

	/**
	 * POST请求https url
	 * 
	 * @param url
	 *            URL
	 * @param json
	 *            请求参数
	 * @param headers
	 *            请求头参数
	 * @return 返回结果
	 * @throws IOException 
	 * @throws NoSuchAlgorithmException 
	 * @throws KeyManagementException 
	 * @throws KeyStoreException 
	 */
	public static String postForHttps(String url, String json, Map<String, String> headers) throws IOException, NoSuchAlgorithmException,
			KeyManagementException, KeyStoreException {
		String result = null;
		CloseableHttpClient httpClient = SimpleHttpsClient.getInstance();

		HttpPost httpPost = new HttpPost(url);
		if (headers != null && headers.size() > 0) {
			for (Entry<String, String> entry : headers.entrySet()) {
				httpPost.setHeader(entry.getKey(), entry.getValue());
			}
		}
		try {
			httpPost.setEntity(new StringEntity(json, "UTF-8"));

			HttpResponse httpResponse = httpClient.execute(httpPost);
			HttpEntity httpEntity = httpResponse.getEntity();
			result = EntityUtils.toString(httpEntity, "UTF-8");
			EntityUtils.consume(httpEntity);
		} finally {
			httpPost.releaseConnection();
			httpClient.close();
		}
		return result;
	}

	/**
	 * 带附件的方法
	 * @param url
	 * @param parameterMap
	 * @param filePath
	 * @return
	 * @throws IOException
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 * @throws KeyStoreException
	 */
	public static String postForHttps(String url, Map<String, Object> parameterMap, String filePath) throws IOException, NoSuchAlgorithmException,
			KeyManagementException, KeyStoreException {
		File file = new File(filePath);
		String result = null;
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);
		MultipartEntityBuilder builder = MultipartEntityBuilder.create();
		try {
			if (parameterMap != null) {
				for (Entry<String, Object> entry : parameterMap.entrySet()) {
					String name = entry.getKey();
					String value = ConvertUtils.convert(entry.getValue());
					if (StringUtils.isNotEmpty(name)) {
						builder.addTextBody(name, value);
					}
				}
			}
			builder.addBinaryBody(file.getName(), file, ContentType.create("application/zip"), file.getName() + ".zip");
			httpPost.setEntity(builder.build());
			HttpResponse httpResponse = httpClient.execute(httpPost);
			HttpEntity httpEntity = httpResponse.getEntity();
			result = EntityUtils.toString(httpEntity, "UTF-8");
			EntityUtils.consume(httpEntity);
		} finally {
			httpPost.releaseConnection();
			httpClient.close();
		}
		return result;
	}

	/**
	 * post请求
	 * @param url 请求地址
	 * @param parameter 参数
	 * @param headers 头信息
	 * @param fileMap 附件
	 * @param contentType 附件的类型
	 * @return
	 * @throws IOException
	 * @throws NoSuchAlgorithmException
	 * @throws KeyManagementException
	 * @throws KeyStoreException
	 */
	public static String postForHttps(String url, Map<String, Object> parameterMap, Map<String, String> headers, Map<String, File> fileMap,
			ContentType contentType) throws IOException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException {
		String result = null;
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpPost httpPost = new HttpPost(url);
		if (headers != null && headers.size() > 0) {
			for (Entry<String, String> entry : headers.entrySet()) {
				httpPost.setHeader(entry.getKey(), entry.getValue());
			}
		}
		MultipartEntityBuilder builder = MultipartEntityBuilder.create();
		try {
			if (parameterMap != null) {
				for (Entry<String, Object> entry : parameterMap.entrySet()) {
					String name = entry.getKey();
					String value = ConvertUtils.convert(entry.getValue());
					if (StringUtils.isNotBlank(name) && StringUtils.isNotBlank(value)) {
						builder.addTextBody(name, value, ContentType.create("text/plain", Charset.forName("UTF-8")));
					}
				}
			}

			File file = null;
			if (fileMap != null && fileMap.size() > 0) {
				for (Entry<String, File> entry : fileMap.entrySet()) {
					file = entry.getValue();
					if (file != null) {
						builder.addBinaryBody(entry.getKey(), file, contentType, file.getName());
					}
				}
			}
			httpPost.setEntity(builder.build());

			HttpResponse httpResponse = httpClient.execute(httpPost);
			HttpEntity httpEntity = httpResponse.getEntity();
			result = EntityUtils.toString(httpEntity, "UTF-8");
			EntityUtils.consume(httpEntity);
		} finally {
			httpPost.releaseConnection();
			httpClient.close();
		}
		return result;
	}

	/**
	 * GET请求
	 * 
	 * @param url
	 *            URL
	 * @param parameterMap
	 *            请求参数
	 * @return 返回结果
	 * @throws IOException 
	 */
	public static String get(String url, Map<String, Object> parameterMap) throws IOException {
		return get(url, parameterMap, null);
	}

	/**
	 * GET请求
	 * 
	 * @param url
	 *            URL
	 * @param parameterMap
	 *            请求参数
	 * @param headers
	 *            请求头
	 * @return 返回结果
	 * @throws IOException 
	 */
	public static String get(String url, Map<String, Object> parameterMap, Map<String, String> headers) throws IOException {
		String result = null;
		CloseableHttpClient httpClient = HttpClients.createDefault();
		HttpGet httpGet = null;
		try {
			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			if (parameterMap != null) {
				for (Entry<String, Object> entry : parameterMap.entrySet()) {
					String name = entry.getKey();
					String value = ConvertUtils.convert(entry.getValue());
					if (StringUtils.isNotEmpty(name)) {
						nameValuePairs.add(new BasicNameValuePair(name, value));
					}
				}
			}
			httpGet = new HttpGet(url + (StringUtils.contains(url, "?") ? "&" : "?") + EntityUtils.toString(new UrlEncodedFormEntity(nameValuePairs, "UTF-8")));
			if (headers != null && headers.size() > 0) {
				for (Entry<String, String> entry : headers.entrySet()) {
					httpGet.setHeader(entry.getKey(), entry.getValue());
				}
			}
			HttpResponse httpResponse = httpClient.execute(httpGet);
			HttpEntity httpEntity = httpResponse.getEntity();
			result = EntityUtils.toString(httpEntity, "UTF-8");
			EntityUtils.consume(httpEntity);
		} finally {
			if (httpGet != null) {
				httpGet.releaseConnection();
			}
			httpClient.close();
		}
		return result;
	}

	/**
	 * POST请求https url
	 * 
	 * @param url
	 *            URL
	 * @param parameterMap
	 *            请求参数
	 * @return 返回结果
	 * @throws IOException 
	 * @throws NoSuchAlgorithmException 
	 * @throws KeyManagementException 
	 * @throws KeyStoreException 
	 */
	public static boolean downLoadPostForHttps(String url, Map<String, String> headerMap, Map<String, Object> parameterMap, String filePath)
			throws IOException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException {
		CloseableHttpClient httpClient = HttpClients.createDefault();

		HttpPost httpPost = new HttpPost(url);
		if (headerMap != null) {
			for (Entry<String, String> entry : headerMap.entrySet()) {
				httpPost.addHeader(entry.getKey(), entry.getValue());
			}
		}
		try {
			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			if (parameterMap != null) {
				for (Entry<String, Object> entry : parameterMap.entrySet()) {
					String name = entry.getKey();
					String value = ConvertUtils.convert(entry.getValue());
					if (StringUtils.isNotEmpty(name)) {
						nameValuePairs.add(new BasicNameValuePair(name, value));
					}
				}
			}
			httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
			HttpResponse httpResponse = httpClient.execute(httpPost);
			HttpEntity httpEntity = httpResponse.getEntity();
			InputStream is = httpEntity.getContent();

			File file = new File(filePath);
			file.getParentFile().mkdirs();

			FileOutputStream fileout = new FileOutputStream(file);

			IOUtils.copy(is, fileout);
			is.close();
			fileout.flush();
			fileout.close();

			EntityUtils.consume(httpEntity);
		} finally {
			httpPost.releaseConnection();
			httpClient.close();
		}
		return true;
	}

	/**
	 * POST请求https url
	 * 
	 * @param url
	 *            URL
	 * @param parameterMap
	 *            请求参数
	 * @return 返回结果
	 * @throws IOException 
	 * @throws NoSuchAlgorithmException 
	 * @throws KeyManagementException 
	 * @throws KeyStoreException 
	 */
	public static boolean downLoadZipGetForHttps(String url, Map<String, String> headerMap, Map<String, Object> parameterMap, String filePath)
			throws IOException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException {
		CloseableHttpClient httpClient = HttpClients.createDefault();

		HttpGet httpGet = null;
		try {
			List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
			if (parameterMap != null) {
				for (Entry<String, Object> entry : parameterMap.entrySet()) {
					String name = entry.getKey();
					String value = ConvertUtils.convert(entry.getValue());
					if (StringUtils.isNotEmpty(name)) {
						nameValuePairs.add(new BasicNameValuePair(name, value));
					}
				}
			}
			httpGet = new HttpGet(url + (StringUtils.contains(url, "?") ? "&" : "?") + EntityUtils.toString(new UrlEncodedFormEntity(nameValuePairs, "UTF-8")));
			if (headerMap != null) {
				for (Entry<String, String> entry : headerMap.entrySet()) {
					httpGet.addHeader(entry.getKey(), entry.getValue());
				}
			}
			HttpResponse httpResponse = httpClient.execute(httpGet);
			HttpEntity httpEntity = httpResponse.getEntity();
			InputStream is = httpEntity.getContent();

			File file = new File(filePath);
			file.getParentFile().mkdirs();

			List<File> files = ZipUtil.unCompressZipFile(is, file.getParent());
			List<String> listFile = new ArrayList<String>();
			for (File f : files) {
				listFile.add(f.getPath());
			}

			ZipUtil zipUtil = ZipUtil.getInstance();
			zipUtil.zipMultiFile(listFile.toArray(new String[listFile.size()]), filePath);

			EntityUtils.consume(httpEntity);

			for (File f : files) {
				FileUtils.deleteQuietly(f);
			}
		} finally {
			if (httpGet != null) {
				httpGet.releaseConnection();
			}
			httpClient.close();
		}
		return true;
	}
}
