package org.testcontainers.junit;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.rnorth.ducttape.unreliables.Unreliables;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.images.builder.ImageFromDockerfile;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

import static org.rnorth.visibleassertions.VisibleAssertions.assertEquals;
import static org.rnorth.visibleassertions.VisibleAssertions.assertTrue;

/**
 * Simple test case / demonstration of creating a fresh container image from a Dockerfile DSL when the test
 * is parameterized.
 */
@RunWith(Parameterized.class)
public class ParameterizedDockerfileContainerTest {

    @Parameterized.Parameters(name = "{0}")
    public static Object[] data() {
        return new Object[] { "alpine:3.2", "alpine:3.3" };
    }

    public ParameterizedDockerfileContainerTest(String baseImage) {
        container = new GenericContainer(new ImageFromDockerfile().withDockerfileFromBuilder(builder -> {
                builder
                        .from(baseImage)
                        .run("apk add --update nginx")
                        .cmd("nginx", "-g", "daemon off;")
                        .build();
            })).withExposedPorts(80);
    }

    @Rule
    public GenericContainer container;

    @Test
    public void simpleTest() throws IOException {
        String address = String.format("http://%s:%s", container.getContainerIpAddress(), container.getMappedPort(80));

        CloseableHttpClient httpClient = HttpClientBuilder.create().build();
        HttpGet get = new HttpGet(address);

        Unreliables.retryUntilSuccess(5, TimeUnit.SECONDS, () -> {
            try (CloseableHttpResponse response = httpClient.execute(get)) {
                assertEquals("A container built from a dockerfile can run nginx as expected, and returns a good status code",
                                200,
                                response.getStatusLine().getStatusCode());
                assertTrue("A container built from a dockerfile can run nginx as expected, and returns an expected Server header",
                                response.getHeaders("Server")[0].getValue().contains("nginx"));
            }
            return true;
        });
    }
}

@@ -32,226 +32,8 @@
 t;%0A%0A
-import org.apache.http.client.methods.CloseableHttpResponse;%0Aimport org.apache.http.client.methods.HttpGet;%0Aimport org.apache.http.impl.client.CloseableHttpClient;%0Aimport org.apache.http.impl.client.HttpClientBuilder;%0A
 impo
@@ -151,60 +151,8 @@
 ed;%0A
-import org.rnorth.ducttape.unreliables.Unreliables;%0A
 impo
@@ -269,150 +269,8 @@
 e;%0A%0A
-import java.io.IOException;%0Aimport java.util.concurrent.TimeUnit;%0A%0Aimport static org.rnorth.visibleassertions.VisibleAssertions.assertEquals;%0A
 impo
@@ -567,149 +567,95 @@
     
-@Parameterized.Parameters(name = %22%7B0%7D%22)%0A    public static Object%5B%5D data() %7B%0A        return new Object%5B%5D %7B %22alpine:3.2%22, %22alpine:3.3%22 %7D;%0A    %7D
+private final String expectedVersion;%0A%0A    @Rule%0A    public GenericContainer container;
 %0A%0A  
@@ -716,16 +716,40 @@
 aseImage
+, String expectedVersion
 ) %7B%0A    
@@ -943,97 +943,124 @@
     
-.run(%22apk add --update nginx%22)%0A                        .cmd(%22nginx%22, %22-g%22, %22daemon off;%22)
+// Could potentially customise the image here, e.g. adding files, running%0A                        //  commands, etc.
 %0A   
@@ -1114,684 +1114,400 @@
 with
-ExposedPorts(80
+Command(%22top%22
 );%0A    
-%7D%0A%0A
     
-@Rule%0A    public GenericContainer container;%0A%0A    @Test%0A    public void simpleTest() throws IOException %7B
+this.expectedVersion = expectedVersion;
 %0A    
+%7D%0A%0A
     
-String address = String.format(%22http://%25s:%25s%22, container.getContainerIpAddress(), container.getMappedPort(80));%0A%0A        CloseableHttpClient httpClient = HttpClientBuilder.create().build();%0A        HttpGet get = new HttpGet(address);%0A%0A        Unreliables.retryUntilSuccess(5, TimeUnit.SECONDS, () -%3E %7B%0A            try (CloseableHttpResponse response = httpClient.execute(get)) %7B%0A                assertEquals(%22A container built from a dockerfile can run nginx as expected, and returns a good status code%22,%0A                    
+@Parameterized.Parameters(name = %22%7B0%7D%22)%0A    public static Object%5B%5D%5B%5D data() %7B%0A        return new Object%5B%5D%5B%5D %7B%0A                %7B %22alpine:3.2%22, %223.2%22%7D,%0A                %7B %22alpine:3.3%22, %223.3%22%7D,%0A                %7B %22alpine:3.4%22, %223.4%22%7D,%0A                %7B %22alpine:3.5%22, %223.5%22%7D,%0A                %7B %22alpine:3.6%22, %223.6%22%7D%0A
         
     
@@ -1506,104 +1506,185 @@
     
+%7D;%0A
     
-200,
+%7D%0A
 %0A    
-                            response.getStatusLine().getStatusCode());%0A    
+@Test%0A    public void simpleTest() throws Exception %7B%0A        final String release = container.execInContainer(%22cat%22, %22/etc/alpine-release%22).getStdout();%0A%0A
         
     
@@ -1679,20 +1679,16 @@
         
-    
 assertTr
@@ -1695,255 +1695,112 @@
 ue(%22
-A container built from a dockerfile can run nginx as expected, and returns an expected Server header%22,%0A                                response.getHeaders(%22Server%22)%5B0%5D.getValue().contains(%22nginx%22));%0A            %7D%0A            return true;%0A        %7D
+/etc/alpine-release starts with %22 + expectedVersion,%0A                release.startsWith(expectedVersion)
 );%0A 

Fix random test failure by removing dependency on Alpine package server. (#505)