package org.forks.jsonrpc;

import java.io.IOException;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.DefaultHttpClient;
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.util.EntityUtils;

public final class HttpJsonRpcClient extends JsonRpcClient {

    private final String mRequestUri;
    final static CookieStore sCookieStore = new BasicCookieStore();
    private static DefaultHttpClient sHttpClient;
    private static String sAppName = "[android] ";

    static {
        HttpParams params = new BasicHttpParams();
        HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
        HttpConnectionParams.setSoTimeout(params, 45 * 1000);
        sHttpClient = new DefaultHttpClient(params);
        sHttpClient.setCookieStore(sCookieStore);
    }

    public HttpJsonRpcClient(String requestUri, String method) {
        super(method);
        mRequestUri = requestUri;
    }

    @Override
    protected String doRequest(String json) throws JsonRpcException {
        HttpPost request = new HttpPost(mRequestUri);
        request.setEntity(newStringEntity(json));
        request.setHeader("User-Agent", sAppName);
        HttpResponse response = getResponse(request);
        return getResponseString(response);
    }

    static void sSetClientAppName(String appName) {
        sAppName = "[android] " + appName;
    }

    private static String getResponseString(HttpResponse response)
            throws JsonRpcException {
        HttpEntity back = response.getEntity();
        try {
            return EntityUtils.toString(back);
        } catch (IOException e) {
            throw new JsonRpcException(e);
        }
    }

    private static StringEntity newStringEntity(String json)
            throws JsonRpcException {
        try {
            return new StringEntity(json, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new JsonRpcException(e);
        }
    }

    private static HttpResponse getResponse(HttpPost request)
            throws JsonRpcException {
        try {
            return sHttpClient.execute(request);
        } catch (ClientProtocolException e) {
            throw new JsonRpcException(e);
        } catch (IOException e) {
            throw new JsonRpcException(e);
        }
    }

}
