package com.heroku.api.httpclient;

import com.google.inject.Inject;
import com.heroku.api.App;
import com.heroku.api.HttpClientModule;
import com.heroku.api.IntegrationTestConfig;
import com.heroku.api.connection.HttpClientConnection;
import com.heroku.api.http.Http;
import com.heroku.api.request.addon.AddonList;
import com.heroku.api.request.app.AppList;
import mockit.Expectations;
import mockit.Mock;
import mockit.MockClass;
import mockit.MockUp;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.EnglishReasonPhraseCatalog;
import org.apache.http.impl.client.AbstractHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHttpResponse;
import org.apache.http.message.BasicStatusLine;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.protocol.HttpContext;
import org.testng.Assert;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;

import java.io.IOException;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;


@Guice(modules = HttpClientModule.class)
public class HttpClientConnectionTest {

    @Inject
    HttpClientConnection connection;

    String apiKey = IntegrationTestConfig.CONFIG.getDefaultUser().getApiKey();


    @Test
    public void asyncTests() throws ExecutionException, TimeoutException, InterruptedException {
        Future<List<App>> jsonArrayResponseFuture = connection.executeAsync(new AppList(), apiKey);
        List<App> jsonArrayResponse = jsonArrayResponseFuture.get(10L, TimeUnit.SECONDS);
        Assert.assertTrue(jsonArrayResponse != null);
    }

    @Test
    public void userAgentShouldContainHerokuJarWithVersionNumber() {
        new MockUp<AbstractHttpClient>() {
            @Mock
            public final HttpResponse execute(HttpUriRequest request, HttpContext context) throws IOException, ClientProtocolException {
                Assert.assertEquals(request.getHeaders(Http.UserAgent.LATEST.getHeaderName())[0].getValue(), Http.UserAgent.LATEST.getHeaderValue("httpclient"));

                BasicHttpResponse basicHttpResponse = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
                basicHttpResponse.setEntity(new StringEntity("[]"));
                return basicHttpResponse;
            }
        };
        connection.execute(new AddonList(), apiKey);
    }

    @Test
    public void cookiesShouldBeIgnored() {
        new MockUp<AbstractHttpClient>() {
            @Mock
            public final HttpResponse execute(HttpUriRequest request, HttpContext context) throws IOException, ClientProtocolException {
                Assert.assertEquals(request.getHeaders("Cookie").length, 0, "Cookies should be ignored, but there are cookies present.");
                BasicHttpResponse basicHttpResponse = new BasicHttpResponse(HttpVersion.HTTP_1_1, HttpStatus.SC_OK, "OK");
                basicHttpResponse.setHeader("Set-Cookie", "foo=bar; path=/;");
                basicHttpResponse.setEntity(new StringEntity("[]"));
                return basicHttpResponse;
            }
        };
        connection.execute(new AddonList(), apiKey);
        // run this twice to ensure the set-cookie was sent from the first request
        connection.execute(new AddonList(), apiKey);
    }
}

@@ -370,87 +370,9 @@
 kit.
-Expectations;%0Aimport mockit.Mock;%0Aimport mockit.MockClass;%0Aimport mockit.MockUp
+*
 ;%0Aim
@@ -1008,49 +1008,9 @@
 ons.
-Guice;%0Aimport org.testng.annotations.Test
+*
 ;%0A%0Ai
@@ -1340,20 +1340,8 @@
  %7B%0A%0A
-    @Inject%0A
     
@@ -1371,16 +1371,45 @@
 nnection
+ = new HttpClientConnection()
 ;%0A%0A    S
@@ -1483,17 +1483,16 @@
 Key();%0A%0A
-%0A
     @Tes
@@ -2589,24 +2589,80 @@
 ), apiKey);%0A
+        Mockit.tearDownMocks(AbstractHttpClient.class);%0A
     %7D%0A%0A    @
@@ -3515,24 +3515,24 @@
 rst request%0A
-
         conn
@@ -3568,20 +3568,76 @@
 ), apiKey);%0A
+        Mockit.tearDownMocks(AbstractHttpClient.class);%0A
     %7D%0A%7D%0A

Fix mock cleanup