package io.airlift.http.client.jetty;

import com.google.common.collect.ImmutableList;
import io.airlift.http.client.AbstractHttpClientTest;
import io.airlift.http.client.HttpClientConfig;
import io.airlift.http.client.HttpRequestFilter;
import io.airlift.http.client.Request;
import io.airlift.http.client.ResponseHandler;
import io.airlift.http.client.TestingRequestFilter;
import io.airlift.http.client.TestingSocksProxy;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.io.Closeable;
import java.io.IOException;

public class TestJettyHttpClientSocksProxy
        extends AbstractHttpClientTest
{
    private JettyHttpClient httpClient;
    private JettyIoPool jettyIoPool;
    private TestingSocksProxy testingSocksProxy;

    @BeforeMethod
    public void setUp()
            throws IOException
    {
        testingSocksProxy = new TestingSocksProxy().start();
        jettyIoPool = new JettyIoPool("test-shared", new JettyIoPoolConfig());
        httpClient = new JettyHttpClient(new HttpClientConfig().setSocksProxy(testingSocksProxy.getHostAndPort()), jettyIoPool, ImmutableList.<HttpRequestFilter>of(new TestingRequestFilter()));
    }

    @AfterMethod
    public void tearDown()
    {
        closeIgnoreException(httpClient);
        closeIgnoreException(jettyIoPool);
        closeIgnoreException(testingSocksProxy);
    }

    @Override
    public <T, E extends Exception> T executeRequest(Request request, ResponseHandler<T, E> responseHandler)
            throws Exception
    {
        return httpClient.execute(request, responseHandler);
    }

    @Override
    public <T, E extends Exception> T executeRequest(HttpClientConfig config, Request request, ResponseHandler<T, E> responseHandler)
            throws Exception
    {
        config.setSocksProxy(testingSocksProxy.getHostAndPort());
        try (
                JettyIoPool jettyIoPool = new JettyIoPool("test-private", new JettyIoPoolConfig());
                JettyHttpClient client = new JettyHttpClient(config, jettyIoPool, ImmutableList.<HttpRequestFilter>of(new TestingRequestFilter()))
        ) {
            return client.execute(request, responseHandler);
        }
    }

    @Override
    @Test(expectedExceptions = IOException.class, expectedExceptionsMessageRegExp = ".*SOCKS4 .*")
    public void testBadPort()
            throws Exception
    {
        // todo this should be handled by jetty client before connecting to the socks proxy
        super.testBadPort();
    }

    @Override
    @Test(enabled = false)
    public void testConnectTimeout()
            throws Exception
    {
        // todo jetty client does not timeout the socks proxy connect properly
        super.testConnectTimeout();
    }

    @Override
    @Test(expectedExceptions = IOException.class, expectedExceptionsMessageRegExp = ".*SOCKS4 .*")
    public void testConnectionRefused()
            throws Exception
    {
        super.testConnectionRefused();
    }

    @Override
    @Test(expectedExceptions = IOException.class, expectedExceptionsMessageRegExp = ".*SOCKS4 .*")
    public void testUnresolvableHost()
            throws Exception
    {
        super.testUnresolvableHost();
    }

    private static void closeIgnoreException(Closeable closeable)
    {
        if (closeable == null) {
            return;
        }
        try {
            closeable.close();
        }
        catch (IOException ignored) {
            // nothing we can do about this
        }
    }
}

@@ -561,45 +561,78 @@
 .io.
-Closeable
+IOException
 ;%0A
+%0A
 import 
-java.io.IOException
+static io.airlift.testing.Closeables.closeQuietly
 ;%0A%0Ap
@@ -1324,31 +1324,23 @@
    close
-IgnoreException
+Quietly
 (httpCli
@@ -1358,31 +1358,23 @@
    close
-IgnoreException
+Quietly
 (jettyIo
@@ -1393,31 +1393,23 @@
    close
-IgnoreException
+Quietly
 (testing
@@ -3263,296 +3263,7 @@
    %7D
-%0A%0A    private static void closeIgnoreException(Closeable closeable)%0A    %7B%0A        if (closeable == null) %7B%0A            return;%0A        %7D%0A        try %7B%0A            closeable.close();%0A        %7D%0A        catch (IOException ignored) %7B%0A            // nothing we can do about this%0A        %7D%0A    %7D
 %0A%7D%0A

Use Closeables.closeQuietly in http client tests