package com.humbughq.mobile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;

import android.net.http.AndroidHttpClient;
import android.os.AsyncTask;
import android.util.Base64;
import android.util.Log;

/// Simplified HTTP request API
public class HTTPRequest {
    ZulipApp app;
    List<NameValuePair> nameValuePairs;
    HttpRequestBase request;
    HttpResponse response;
    volatile boolean aborting = false;

    HTTPRequest(ZulipApp app) {
        nameValuePairs = new ArrayList<NameValuePair>();
        this.app = app;
    }

    public void setProperty(String key, String value) {
        this.nameValuePairs.add(new BasicNameValuePair(key, value));
    }

    public void clearProperties() {
        this.nameValuePairs.clear();
    }

    public void abort() {
        aborting = true;
        if (request != null) {
            (new AsyncTask<Void, Void, Void>() {
                @Override
                protected Void doInBackground(Void... voids) {
                    request.abort();
                    return null;
                }
            }).execute();
        }
    }

    String execute(String method, String path) throws IOException {
        AndroidHttpClient httpclient = AndroidHttpClient.newInstance(app
                .getUserAgent());

        String responseString = null;
        try {
            String url = app.getServerURI() + path;
            nameValuePairs.add(new BasicNameValuePair("client", "Android"));

            // Only POST, PUT and GET are supported, for now.
            if (method.equals("POST")) {
                request = new HttpPost(url);
                ((HttpEntityEnclosingRequestBase) request)
                        .setEntity(new UrlEncodedFormEntity(nameValuePairs,
                                "UTF-8"));
            } else if (method.equals("PUT")) {
                request = new HttpPut(url);
                ((HttpEntityEnclosingRequestBase) request)
                        .setEntity(new UrlEncodedFormEntity(nameValuePairs,
                                "UTF-8"));
            } else {
                request = new HttpGet(url + "?"
                        + URLEncodedUtils.format(nameValuePairs, "utf-8"));
            }

            Log.i("HTTP.request", request.getMethod() + " " + request.getURI());

            String authstr = this.app.getEmail() + ":" + this.app.getApiKey();
            request.setHeader(
                    "Authorization",
                    "Basic "
                            + Base64.encodeToString(authstr.getBytes(),
                                    Base64.NO_WRAP));
            // timeout after 60 seconds in ms
            HttpConnectionParams.setSoTimeout(request.getParams(), 60 * 1000);

            response = httpclient.execute(request);

            StatusLine statusLine = response.getStatusLine();

            ByteArrayOutputStream out = new ByteArrayOutputStream();
            response.getEntity().writeTo(out);
            out.close();
            responseString = out.toString();
            if (statusLine.getStatusCode() != HttpStatus.SC_OK) {
                Log.e("HTTP", statusLine.getReasonPhrase());
                Log.e("HTTP", responseString);
                throw new HttpResponseException(statusLine.getStatusCode(),
                        responseString);
            }
        } finally {
            httpclient.close();
        }

        if (responseString != null) {
            Log.i("HTTP.response", responseString);
        } else {
            Log.i("HTTP.response", "<empty>");
        }
        return responseString;
    }
}

@@ -1840,24 +1840,350 @@
    %7D%0A    %7D%0A%0A
+    // Java doesn't support a request body on DELETE requests, but RFC2616 does%0A    // not prohibit it.%0A    class HttpDeleteWithReq extends HttpPost %7B%0A        HttpDeleteWithReq(String url) %7B%0A            super(url);%0A        %7D%0A%0A        @Override%0A        public String getMethod() %7B%0A            return %22DELETE%22;%0A        %7D%0A    %7D%0A%0A
     String e
@@ -2532,70 +2532,8 @@
 );%0A%0A
-            // Only POST, PUT and GET are supported, for now.%0A
     
@@ -2630,171 +2630,188 @@
     
-    ((HttpEntityEnclosingRequestBase) request)%0A                        .setEntity(new UrlEncodedFormEntity(nameValuePairs,%0A                                %22UTF-8%22)
+%7D else if (method.equals(%22PUT%22)) %7B%0A                request = new HttpPut(url);%0A            %7D else if (method.equals(%22DELETE%22)) %7B%0A                request = new HttpDeleteWithReq(url
 );%0A 
@@ -2839,34 +2839,34 @@
 (method.equals(%22
-PU
+GE
 T%22)) %7B%0A         
@@ -2886,33 +2886,169 @@
 t = new Http
-Pu
+Ge
 t(url
-);
+ + %22?%22%0A                        + URLEncodedUtils.format(nameValuePairs, %22utf-8%22));%0A            %7D%0A%0A            if (!method.equals(%22GET%22)) %7B
 %0A           
@@ -3231,153 +3231,8 @@
    %7D
- else %7B%0A                request = new HttpGet(url + %22?%22%0A                        + URLEncodedUtils.format(nameValuePairs, %22utf-8%22));%0A            %7D
 %0A%0A  

Support DELETE in HttpRequest