package com.pccw.hktdcb.apiserver.util;

import it.sauronsoftware.base64.Base64;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ClientConnectionManager;
import org.apache.http.conn.scheme.PlainSocketFactory;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.scheme.SchemeRegistry;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HttpsRequestUtil {
protected static final Logger logger = LoggerFactory
.getLogger(HttpsRequestUtil.class);
private static final int TIME_OUT = Integer.parseInt(SystemConfig
.getProperty("https_client_timeout")) * 1000;

public static HttpClient getHttpClient() {

@SuppressWarnings("deprecation")
HttpClient httpclient = new DefaultHttpClient();
try {
// Secure Protocol implementation.
SSLContext ctx = SSLContext.getInstance("SSL");

// Implementation of a trust manager for X509 certificates
X509TrustManager tm = new X509TrustManager() {

public void checkClientTrusted(X509Certificate[] xcs,
String string) throws CertificateException {

}

public void checkServerTrusted(X509Certificate[] xcs,
String string) throws CertificateException {
}

public X509Certificate[] getAcceptedIssuers() {
return null;
}
};

X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {

public boolean verify(String hostname, SSLSession session) {
// TODO Auto-generated method stub
return true;
}

public void verify(String arg0, SSLSocket arg1)
throws IOException {
// TODO Auto-generated method stub

}

public void verify(String arg0, X509Certificate arg1)
throws SSLException {
// TODO Auto-generated method stub

}

public void verify(String arg0, String[] arg1, String[] arg2)
throws SSLException {
// TODO Auto-generated method stub

}
};

ctx.init(null, new TrustManager[] { tm }, null);
SSLSocketFactory ssf = new SSLSocketFactory(ctx, hostnameVerifier);

ClientConnectionManager ccm = httpclient.getConnectionManager();
// register https protocol in httpclient's scheme registry
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", 443, ssf));
sr.register(new Scheme("http", 80, PlainSocketFactory
.getSocketFactory()));

// set Time out
httpclient.getParams().setParameter(
CoreConnectionPNames.CONNECTION_TIMEOUT, TIME_OUT);
httpclient.getParams().setParameter(
CoreConnectionPNames.SO_TIMEOUT, TIME_OUT);

} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (KeyManagementException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

return httpclient;

}

public static String getHTTPSRequest(String url, String userName,
String password) {

logger.info("HttpsRequestUtil : getHTTPSRequest start............");
logger.debug("url : " + url);
String result = null;

HttpGet httpget = new HttpGet(url);
try {

String authString = userName + ":" + password;
String authStringEnc = new String(Base64.encode(authString
.getBytes()));

httpget.addHeader("Authorization", "Basic " + authStringEnc);
httpget.addHeader("content-type", "application/json");
httpget.addHeader("accept", "application/json");

HttpClient httpclient = getHttpClient();
HttpResponse response = httpclient.execute(httpget);
if (response != null) {
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
int httpStatus = response.getStatusLine().getStatusCode();
if (httpStatus == HttpStatus.SC_OK) {
result = EntityUtils.toString(resEntity, "UTF-8");
} else {
logger.error(
"HttpsRequestUtil : getHTTPSRequest failed, http status code is [{}]",
httpStatus);
}
}
}

logger.debug("HttpsRequestUtil : getHTTPSRequest;result = "
+ result);

} catch (ClientProtocolException e) {
logger.error(
"HttpsRequestUtil : getHTTPSRequest error occur, Exception is [{}]",
e.getMessage());
} catch (IOException e) {
logger.error(
"HttpsRequestUtil : getHTTPSRequest error occur, Exception is [{}]",
e.getMessage());
} finally {
httpget.releaseConnection();
}

logger.info("HttpsRequestUtil : getHTTPSRequest end........");
return result;
}

}