package com.backfire.php;

import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
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.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.protocol.HTTP;
import org.apache.http.util.EntityUtils;

import com.backfire.php.PHPResult.ErrorCode;
import com.backfire.utils.Log;
/**
 * @author wf
 *
 */

public class PHPConnect {
	private static final Integer connectionTimeout = 20*1000;
	private static final Integer socketTimeout = 20 * 1000;
	private static final Integer socketBufferSize = 8*1024;
	private static final Boolean isTcpNoDelay = false;
	private static final Boolean isStaleCheckingEnabled = false;
	private static final Boolean isRedirecting = false;
	private static final String base_Url1="ddz-ucl-02.13958.com";
	private static final String base_Url2="ddzucl02.13958.com";
	/*private static final String base_Url1="42.62.56.178";
	private static final String base_Url2="42.62.56.178";*/
	
	private static final Integer base_port=11113;
	private static final String backup_Url = "http://42.62.67.42:"+base_port;
//	private static final String backup_Url = "http://42.62.56.178:"+base_port;
	
	private static  String s_Url = "douniu/";
	
	public static  String pay_url = "bill/";
	public static  String pay_base_url = "bill/";
	private static boolean 	selectedFlag = false; 
	
	
	private ArrayList <String> urlList = new ArrayList<String>();
	public String requestMethod = null;
	private static String requestUrl = s_Url;
	private String requestBody = null;
	public PHPResult result = new PHPResult();
	private HttpPost request;
	/**
	 * 
	 */
	public PHPConnect(String method, String postData) {
		this.requestMethod = method;
		this.requestBody = postData;
		//selectUrl();
	}

	/**
	 * 选择出能连接成功的URL
	 * @return 
	 */
	public void selectUrl() {
		if(selectedFlag) {
			Log.i("PHP", "selectedFlag == SELECTED");
			return ;
		}
		urlList.clear();
		int temp = (int) (Math.random()*2);
		if(temp>0){
			urlList.add(getUrlFormHost(base_Url1));
			urlList.add(getUrlFormHost(base_Url2));
		}else{
			urlList.add(getUrlFormHost(base_Url2));
			urlList.add(getUrlFormHost(base_Url1));
		}
		for(String url : urlList){
			if(url!=null && cofigUrl(url+s_Url) != null) {
				Log.i("PHP", "urlList:" + url);
				selectedFlag = true;
				requestUrl = url+s_Url;
				pay_url = url+pay_base_url;
				return ;
			}
		}
		//什么都没找到，直接返回空
		Log.v("PHP", "selectUrl=" + requestUrl );
		selectedFlag = true;
		requestUrl = backup_Url+s_Url;
		pay_url = backup_Url+pay_base_url;
	}
	private String getUrlFormHost(String host){
		Log.i(this, "host:"+host);
		try {
			//InetAddress IP =InetAddress.getAllByName(host)[0];
			InetAddress IP =InetAddress.getByName(host);
			host = IP.getHostAddress();
		} catch (Exception e) {
			Log.e(this, e);
		}
		Log.i(this, "host:"+host);
		return "http://"+host+":"+base_port+"/";
	}
	
	public String cofigUrl(String url){
		Log.v("PHP", "test Url:" + url);
		String retStr = null;
		HttpClient client = createHTTPClient();
		HttpGet request = new HttpGet(url);
		result.reset();
		HttpResponse response = null;
		try {
			response = client.execute(request);
		} catch (ClientProtocolException e){
			Log.w("PHPGet", e);
			result.code = ErrorCode.NETWORK_ERROR;
		}
		catch (IOException e){
			Log.w("PHPGet", e);
			result.code = ErrorCode.NETWORK_ERROR;
		}
		catch (IllegalStateException e) {
			Log.w("PHPGet", e);
			result.code = ErrorCode.NETWORK_ERROR;
		}catch (Exception e) {
			Log.w("PHPGet", e);
			result.code = ErrorCode.NETWORK_ERROR;
		}
		finally{
			if(response != null) {
				if(response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK) {
					retStr = url;
				}
			}
		}
		return retStr;		
	}
	private HttpClient createHTTPClient()
	{
		HttpParams httpParams = new BasicHttpParams(); // 创建HttpParams以用来设置HTTP参数（这一部分不是必需的）
		HttpConnectionParams
				.setConnectionTimeout(httpParams, connectionTimeout); // 设置连接超时
		HttpConnectionParams.setSoTimeout(httpParams, socketTimeout); // 设置Socket超时
		HttpConnectionParams.setSocketBufferSize(httpParams, socketBufferSize); // Socket数据缓存默认8K
		HttpConnectionParams.setTcpNoDelay(httpParams, isTcpNoDelay);
		HttpConnectionParams.setStaleCheckingEnabled(httpParams, isStaleCheckingEnabled);
		HttpClientParams.setRedirecting(httpParams, isRedirecting);
		return new DefaultHttpClient(httpParams);
	}

	
	public void postRequest() {
		selectUrl();		//该段代码不能在主线程中执行，严苛模式执行会出错
		HttpResponse response = null;
		try {
			Log.v("PHP", "Post Url:" + requestUrl);
			Log.v("PHP", "cmd:" + this.requestMethod);
			HttpClient client = createHTTPClient();				//如果没有网络时该方法会抛出异常，故需捕获
			//ByteArrayEntity formEntity = new ByteArrayEntity(this.requestBody);
			request = new HttpPost(requestUrl);		//requestUrl为null时会异常
			
			//request.setEntity(formEntity);
			
			
			List<NameValuePair> postParams = new ArrayList<NameValuePair>(2);
			postParams.add(new BasicNameValuePair("BF", this.requestBody));
			Log.v(this, this.requestBody);
			UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(
					postParams, HTTP.UTF_8);
			request.setEntity(formEntity);
			
			request.addHeader("CMD", this.requestMethod);
			result.reset();
			//执行post动作
			response = client.execute(request);
		} catch (ClientProtocolException e) {
			Log.w("PHPPost", "ClientProtocolException");
			result.code = ErrorCode.NETWORK_ERROR;
		} catch (IOException e) {
			Log.w("PHPPost", "IOException " + e.toString());
			result.code = ErrorCode.NETWORK_ERROR;
		}catch (Exception e) {
			Log.w("PHPPost", "Exception " + e.toString());
			result.code = ErrorCode.NETWORK_ERROR;
		}
		finally
		{
			if (response != null)
			{
				if (response.getStatusLine().getStatusCode() == HttpURLConnection.HTTP_OK) {
					String res = null;
					try {
						res = EntityUtils.toString(response.getEntity(),"UTF-8");
					} catch (Exception e) {
						Log.w("PHPPost", "EntityUtils IOException");
						result.code = ErrorCode.NETWORK_ERROR;
					}
					if(res!=null && res.length()>0)explainResult(res);
					else{
						Log.w("PHPPost", "EntityUtils IOException");
						result.code = ErrorCode.NETWORK_ERROR;
					}
				}
				else
				{
					Log.w("PHPPost", "CONNECTION_ERROR "+response.getStatusLine().getStatusCode());
					result.code = ErrorCode.NETWORK_ERROR;
				}
			}
		}
	}
	public void abort(){
		if(request!=null)request.abort();
	}
	private void explainResult(String res){
		Log.v(this, res);
		result.code = ErrorCode.SUCCESS;
		result.recvData = res;
	}
	/*
	 * 重写equals方法，用来比较两个请求是否是同一个请求
	 * 比较原理：发送数据不同或请求方法不同
	 */
	public boolean equals(PHPConnect postData) {
		//是否为空判断
		if(this.requestMethod==null 
				|| postData.requestMethod==null
				|| this.requestBody==null
				|| postData.requestBody==null) return false;
		//方法名是否相同判断
		if(!this.requestMethod.equals(postData.requestMethod))return false;
		//发送数据是否一样判断
		if(!this.requestBody.equalsIgnoreCase(postData.requestBody)) return false;
		return true;
	}
}
