package com.android.chat.lib;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
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.client.params.HttpClientParams;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;

/**
* @描述 网络工具类
* @项目名称 App_Chat
* @包名 com.android.chat.lib
* @类名 HttpManaer
* @author chenlin
* @date 2012年6月26日 下午3:16:39
* @version 1.0
*/
public class HttpManaer {
private final static String ERROR = "error";

//参数
private HttpParams httpParams;
//http客户端
private HttpClient httpClient;
//使用单例模式------------------------------------------
private static HttpManaer instance;

/**
* @param userAgent: 可以是任何数据
* @return
*/
public static HttpManaer getInstance() {
if (instance == null) {
synchronized (HttpManaer.class) {
if (instance == null) {
instance = new HttpManaer();
}
}
}
return instance;
}

private HttpManaer() {
// 创建 HttpParams 以用来设置 HTTP 参数(这一部分不是必需的)
this.httpParams = new BasicHttpParams();
// 设置连接超时和 Socket 超时,以及 Socket 缓存大小
HttpConnectionParams.setConnectionTimeout(httpParams, 20 * 1000);
HttpConnectionParams.setSoTimeout(httpParams, 20 * 1000);
HttpConnectionParams.setSocketBufferSize(httpParams, 8192);
// 设置重定向,缺省为 true
HttpClientParams.setRedirecting(httpParams, true);
// 设置 user agent
String userAgent = "HttpComponents/1.1";
HttpProtocolParams.setUserAgent(httpParams, userAgent );
// 创建一个 HttpClient 实例
httpClient = new DefaultHttpClient(httpParams);
}

/**
* doGet连接
* @param url
* @param headers
* @param params
* @return
*/
public String doGet(String url, Map<String, String> headers, Map<String, String> params) {
/* 建立HTTPGet对象 */
String paramStr = "";
HttpGet httpGet = new HttpGet(url);
String result = ERROR;

if (headers != null) {
for (Map.Entry<String, String> me : headers.entrySet()) {
String key = me.getKey();
String value = me.getValue();
httpGet.setHeader(key, value);
}
}

if (params != null) {
for (Map.Entry<String, String> map : params.entrySet()) {
String key = map.getKey();
String value = map.getValue();
paramStr += paramStr = "&" + key + "=" + value;
}

//连接第二个
if (!"".equals(paramStr)) {
paramStr = paramStr.replaceFirst("&", "?");
url += paramStr;
}
}

try {
/* 发送请求并等待响应 */
HttpResponse response = httpClient.execute(httpGet);
/* 若状态码为200 ok */
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
/* 读返回数据 */
result = EntityUtils.toString(response.getEntity());
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}

/**
* doPost请求
* @param url
* @param headers
* @param params
* @return
*/
public String doPost(String url, Map<String, String> headers, List<NameValuePair> params) {
/* 建立HTTPPost对象 */
HttpPost post = new HttpPost(url);
String result = ERROR;

if (headers != null) {
for (Map.Entry<String, String> me : headers.entrySet()) {
String key = me.getKey();
String value = me.getValue();

post.setHeader(key, value);
}
}

try {
/* 添加请求参数到请求对象 */
post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
/* 发送请求并等待响应 */
HttpResponse response = httpClient.execute(post);
/* 若状态码为200 ok */
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
/* 读返回数据 */
result = EntityUtils.toString(response.getEntity());
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}

/**
* 文件上传
* @param url
* @param headers
* @param params
* @param files
* @return
*/
public String doUpload(String url, Map<String, String> headers, List<NameValuePair> params, Map<String, File> files) {
/* 建立HTTPPost对象 */
HttpPost post = new HttpPost(url);
String result = ERROR;

MultipartEntity multipartEntity = new MultipartEntity();

if (headers != null) {
for (Map.Entry<String, String> me : headers.entrySet()) {
String key = me.getKey();
String value = me.getValue();

post.setHeader(key, value);
}
}
try {

if (params != null) {
for (NameValuePair pair : params) {
multipartEntity.addPart(pair.getName(),
new StringBody(pair.getValue(), Charset.forName(HTTP.UTF_8)));
}
}

if (files != null) {
for (Map.Entry<String, File> map : files.entrySet()) {
String key = map.getKey();
File file = map.getValue();

multipartEntity.addPart(key, new FileBody(file, HTTP.UTF_8));
}
}

/* 添加请求参数到请求对象 */
post.setEntity(multipartEntity);
/* 发送请求并等待响应 */
HttpResponse response = httpClient.execute(post);
/* 若状态码为200 ok */
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
/* 读返回数据 */
result = EntityUtils.toString(response.getEntity());
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}

/**
* 文件下载
* @param url
* @param headers :头文件
* @param params :传输的参数
* @param localFile
* @return
*/
public String doDownload(String url, Map<String, String> headers, List<NameValuePair> params, File localFile) {
/* 建立HTTPPost对象 */
HttpPost post = new HttpPost(url);
String result = ERROR;

if (headers != null) {
for (Map.Entry<String, String> me : headers.entrySet()) {
String key = me.getKey();
String value = me.getValue();

post.setHeader(key, value);
}
}

try {
/* 添加请求参数到请求对象 */
post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));
/* 发送请求并等待响应 */
HttpResponse response = httpClient.execute(post);
/* 若状态码为200 ok */
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
//创建文件夹
File dir = localFile.getParentFile();
if (!dir.exists()) {
dir.mkdirs();
}

/* 读返回数据 */
InputStream stream = response.getEntity().getContent();
FileOutputStream fos = new FileOutputStream(localFile);
byte[] buffer = new byte[1024];
int len = -1;

while ((len = stream.read(buffer)) != -1) {
fos.write(buffer, 0, len);
fos.flush();
}
stream.close();
fos.close();

}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}

/** {‘flag’:true,’data’:{‘name’:’张三’,’age’:18,’sex’:true}}
*
* {‘flag’:false,’errorCode’:404, ‘errorString’:’服务器没响应’}
*
* post提交Json数据
* @param url
* @param headers
* @param paramaters
* @return
*/
public boolean post(String url, Map<String, String> headers, Map<String, String> paramaters) {
List<NameValuePair> params = new ArrayList<NameValuePair>();

if (paramaters != null) {
for (Map.Entry<String, String> me : paramaters.entrySet()) {
params.add(new BasicNameValuePair(me.getKey(), me.getValue()));
}
}
String result = doPost(url, headers, params);

return parseResult(result);
}

private boolean parseResult(String result) {
if (ERROR.equals(result)) {
return false;
} else {
JsonParser parser = new JsonParser();
try {
JsonObject root = parser.parse(result).getAsJsonObject();
JsonPrimitive flagObject = root.getAsJsonPrimitive("flag");
//判断是否成功
return flagObject.getAsBoolean();
} catch (Exception e) {
return false;
}
}
}

/**
* 下载
* @param url
* @param headers
* @param paramaters :map形式封装参数
* @param localFile
* @return
*/
public boolean download(String url, Map<String, String> headers, Map<String, String> paramaters, File localFile) {
List<NameValuePair> params = new ArrayList<NameValuePair>();

if (paramaters != null) {
for (Map.Entry<String, String> map : paramaters.entrySet()) {
params.add(new BasicNameValuePair(map.getKey(), map.getValue()));
}
}

String result = doDownload(url, headers, params, localFile);
return parseResult(result);
}

/**
* 上传文件
* @param url
* @param headers
* @param paramaters
* @param filePaths
* @return
*/
public boolean upload(String url, Map<String, String> headers, Map<String, String> paramaters,
Map<String, String> filePaths) {

List<NameValuePair> params = new ArrayList<NameValuePair>();

if (paramaters != null) {
for (Map.Entry<String, String> me : paramaters.entrySet()) {
params.add(new BasicNameValuePair(me.getKey(), me.getValue()));
}
}

Map<String, File> files = new HashMap<String, File>();
if (filePaths != null) {

for (Map.Entry<String, String> me : filePaths.entrySet()) {
String key = me.getKey();
String value = me.getValue();

files.put(key, new File(value));
}

}

String result = doUpload(url, headers, params, files);
return parseResult(result);
}
}