<commit_before>package com.group5.android.fd.helper;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
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.methods.HttpUriRequest;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.net.http.AndroidHttpClient;
import android.util.Log;

import com.group5.android.fd.FdConfig;
import com.group5.android.fd.R;

public class HttpHelper {

	final public static String ERROR_MESSAGE_CONNECT_TIMEOUT = "Oops, connection timed out!";

	public static HashMap<String, HttpContext> contexts = new HashMap<String, HttpContext>();

	/**
	 * Sends a HTTP GET request to the target uri and parses the response as an
	 * <code>JSONObject</code>
	 * 
	 * @param strUri
	 *            the target uri
	 * @return an <code>JSONObject</code>
	 */
	public static JSONObject get(String strUri) {
		JSONObject jsonResponse = null;

		Log.i(FdConfig.DEBUG_TAG, "HttpHelper.get(): " + strUri);

		try {
			URI uri = new URI(strUri);
			HttpGet request = new HttpGet(uri);

			jsonResponse = HttpHelper.execute(uri, request);
		} catch (URISyntaxException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return jsonResponse;
	}

	/**
	 * Sends a HTTP POST request and parses the response as an
	 * <code>JSONObject</code>. It's required that all POST request must include
	 * a CSRF token so this method is designed to receive the token as a
	 * parameter for easy access. However, you can pass NULL to params if you
	 * want
	 * 
	 * @param strUri
	 *            the target uri
	 * @param csrfToken
	 *            the required CSRF token
	 * @param params
	 *            a list of POST parameters
	 * @return an <code>JSONObject</code>
	 */
	public static JSONObject post(String strUri, String csrfToken,
			List<NameValuePair> params) {
		JSONObject jsonResponse = null;

		Log.i(FdConfig.DEBUG_TAG, "HttpHelper.post(): " + strUri);

		try {
			URI uri = new URI(strUri);
			HttpPost request = new HttpPost(uri);
			if (params == null) {
				// create new name value list if null is supplied
				params = new ArrayList<NameValuePair>();
			}
			if (csrfToken != null) {
				// set the csrf token
				// this is required for all POST requests
				// with the exception of login request, of course
				params.add(new BasicNameValuePair("_xfToken", csrfToken));
			}
			request.setEntity(new UrlEncodedFormEntity(params));

			for (int pi = 0; pi < params.size(); pi++) {
				Log.d(FdConfig.DEBUG_TAG, "HttpHelper.post(): "
						+ params.get(pi).getName() + " = "
						+ params.get(pi).getValue());
				// this debug loop is very ineffective
				// we should remove it entirely at somepoint
				// TODO: remove this debug loop
			}

			jsonResponse = HttpHelper.execute(uri, request);
		} catch (URISyntaxException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return jsonResponse;
	}

	protected static JSONObject execute(URI uri, HttpUriRequest request) {
		JSONObject jsonResponse = null;
		AndroidHttpClient httpClient = AndroidHttpClient
				.newInstance(FdConfig.HTTP_REQUEST_USER_AGENT);

		try {
			HttpContext httpContext = HttpHelper.getContext(uri);

			HttpResponse response = httpClient.execute(request, httpContext);
			HttpEntity httpEntity = response.getEntity();
			InputStream inputStream = httpEntity.getContent();
			String string = HttpHelper.streamToString(inputStream);

			Log.d(FdConfig.DEBUG_TAG, "HttpHelper.execute(): " + string);

			jsonResponse = new JSONObject(string);
		} catch (ConnectTimeoutException e) {
			jsonResponse = new JSONObject();
			try {
				JSONArray error = new JSONArray();
				error.put(HttpHelper.ERROR_MESSAGE_CONNECT_TIMEOUT);
				jsonResponse.put("error", error);
			} catch (JSONException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}

			Log.d(FdConfig.DEBUG_TAG, "HttpHelper.execute(): Timeout");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		httpClient.close();

		return jsonResponse;
	}

	/**
	 * Create or reuse HttpContext for each host. Also enables the context to
	 * store cookies between requests
	 * 
	 * @param uri
	 * @return an instance of HttpContext
	 */
	protected static HttpContext getContext(URI uri) {
		String host = uri.getHost();

		if (HttpHelper.contexts.containsKey(host)) {
			return HttpHelper.contexts.get(host);
		} else {
			HttpContext context = new BasicHttpContext();
			CookieStore cookieStore = new BasicCookieStore();
			context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);

			HttpHelper.contexts.put(host, context);
			return context;
		}
	}

	/**
	 * Simple way to turn an input stream to a string<commit_msg>add HttpHelper.getRaw() which returns an InputStream<commit_after>package com.group5.android.fd.helper;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
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.methods.HttpUriRequest;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.net.http.AndroidHttpClient;
import android.util.Log;

import com.group5.android.fd.FdConfig;
import com.group5.android.fd.R;

public class HttpHelper {

	final public static String ERROR_MESSAGE_CONNECT_TIMEOUT = "Oops, connection timed out!";

	final public static int RESPONSE_TYPE_JSON = 1;
	final public static int RESPONSE_TYPE_RAW = 2;

	public static HashMap<String, HttpContext> contexts = new HashMap<String, HttpContext>();

	/**
	 * Sends a HTTP GET request to the target uri and parses the response as an
	 * <code>JSONObject</code>
	 * 
	 * @param strUri
	 *            the target uri
	 * @param responseType
	 * @return an <code>JSONObject</code> or an <code>InputStream</code>
	 */
	public static Object get(String strUri, int responseType) {
		Object response = null;

		Log.i(FdConfig.DEBUG_TAG, "HttpHelper.get(): " + strUri);

		try {
			URI uri = new URI(strUri);
			HttpGet request = new HttpGet(uri);

			response = HttpHelper.execute(uri, request, responseType);
		} catch (URISyntaxException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return response;
	}

	public static JSONObject get(String strUri) {
		Object response = HttpHelper.get(strUri, HttpHelper.RESPONSE_TYPE_JSON);

		if (response != null) {
			return (JSONObject) response;
		} else {
			return null;
		}
	}

	public static InputStream getRaw(String strUri) {
		Object response = HttpHelper.get(strUri, HttpHelper.RESPONSE_TYPE_RAW);

		if (response != null) {
			return (InputStream) response;
		} else {
			return null;
		}
	}

	/**
	 * Sends a HTTP POST request and parses the response as an
	 * <code>JSONObject</code>. It's required that all POST request must include
	 * a CSRF token so this method is designed to receive the token as a
	 * parameter for easy access. However, you can pass NULL to params if you
	 * want
	 * 
	 * @param strUri
	 *            the target uri
	 * @param csrfToken
	 *            the required CSRF token
	 * @param params
	 *            a list of POST parameters
	 * @param responseType
	 * @return an <code>JSONObject</code> or an <code>InputStream</code>
	 */
	public static Object post(String strUri, String csrfToken,
			List<NameValuePair> params, int responseType) {
		Object response = null;

		Log.i(FdConfig.DEBUG_TAG, "HttpHelper.post(): " + strUri);

		try {
			URI uri = new URI(strUri);
			HttpPost request = new HttpPost(uri);
			if (params == null) {
				// create new name value list if null is supplied
				params = new ArrayList<NameValuePair>();
			}
			if (csrfToken != null) {
				// set the csrf token
				// this is required for all POST requests
				// with the exception of login request, of course
				params.add(new BasicNameValuePair("_xfToken", csrfToken));
			}
			request.setEntity(new UrlEncodedFormEntity(params));

			for (int pi = 0; pi < params.size(); pi++) {
				Log.d(FdConfig.DEBUG_TAG, "HttpHelper.post(): "
						+ params.get(pi).getName() + " = "
						+ params.get(pi).getValue());
				// this debug loop is very ineffective
				// we should remove it entirely at somepoint
				// TODO: remove this debug loop
			}

			response = HttpHelper.execute(uri, request, responseType);
		} catch (URISyntaxException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return response;
	}

	public static JSONObject post(String strUri, String csrfToken,
			List<NameValuePair> params) {
		Object response = HttpHelper.post(strUri, csrfToken, params,
				HttpHelper.RESPONSE_TYPE_JSON);

		if (response != null) {
			return (JSONObject) response;
		} else {
			return null;
		}
	}

	protected static Object execute(URI uri, HttpUriRequest request,
			int responseType) {
		Object response = null;
		InputStream inputStream = null;
		AndroidHttpClient httpClient = AndroidHttpClient
				.newInstance(FdConfig.HTTP_REQUEST_USER_AGENT);

		try {
			HttpContext httpContext = HttpHelper.getContext(uri);

			HttpResponse httpResponse = httpClient
					.execute(request, httpContext);
			HttpEntity httpEntity = httpResponse.getEntity();
			inputStream = httpEntity.getContent();
		} catch (ConnectTimeoutException e) {
			try {
				inputStream = new ByteArrayInputStream(new String(
						"{\"error\":\""
								+ HttpHelper.ERROR_MESSAGE_CONNECT_TIMEOUT
								+ "\"}").getBytes("UTF-8"));
			} catch (UnsupportedEncodingException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}

			Log.d(FdConfig.DEBUG_TAG, "HttpHelper.execute(): Timeout");
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			switch (responseType) {
			case RESPONSE_TYPE_JSON:
				response = new JSONObject(HttpHelper
						.streamToString(inputStream));
				break;
			case RESPONSE_TYPE_RAW:
				response = inputStream;
				break;
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		httpClient.close();

		return response;
	}

	/**
	 * Create or reuse HttpContext for each host. Also enables the context to
	 * store cookies between requests
	 * 
	 * @param uri
	 * @return an instance of HttpContext
	 */
	protected static HttpContext getContext(URI uri) {
		String host = uri.getHost();

		if (HttpHelper.contexts.containsKey(host)) {
			return HttpHelper.contexts.get(host);
		} else {
			HttpContext context = new BasicHttpContext();
			CookieStore cookieStore = new BasicCookieStore();
			context.setAttribute(ClientContext.COOKIE_STORE, cookieStore);

			HttpHelper.contexts.put(host, context);
			return context;
		}
	}

	/**
	 * Simple way to turn an input stream to a string
{'fraction_non_alphanumeric': 0.10501960784313726, 'fraction_numerical': 0.001176470588235294, 'mean_word_length': 3.7990214527662776, 'pattern_counts': {'":': 1, '<': 34, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2487824', 'n_tokens_mistral': 4280, 'n_tokens_neox': 3758, 'n_words': 1040}