package pl.touk.sputnik.connector.stash;

import com.github.tomakehurst.wiremock.WireMockServer;
import com.github.tomakehurst.wiremock.client.WireMock;
import com.github.tomakehurst.wiremock.core.WireMockConfiguration;
import com.github.tomakehurst.wiremock.http.HttpClientFactory;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.util.EntityUtils;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import pl.touk.sputnik.configuration.ConfigurationSetup;
import pl.touk.sputnik.review.ReviewFile;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.github.tomakehurst.wiremock.client.WireMock.*;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
import static junit.framework.Assert.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.core.IsInstanceOf.instanceOf;

public class StashFacadeHttpsTest {

    private static Integer PORT = 8089;
    private static Integer HTTPS_PORT = 8443;
    private static final ImmutableMap<String, String> STASH_CONFIG_MAP = ImmutableMap.of(
            "stash.host", "localhost",
            "stash.port", HTTPS_PORT.toString(),
            "stash.username", "user",
            "stash.password", "pass",
            "stash.useHttps", "true"
    );
    private static final ImmutableMap<String, String> STASH_PATCHSET_MAP = ImmutableMap.of(
            "cli.pullRequestId", "12",
            "stash.repositorySlug", "myproject",
            "stash.projectKey", "mykey"
    );

    private StashFacade stashFacade;
    private WireMockServer wireMockServer;
    private HttpClient httpClient;


    @After
    public void serverShutdown() {
        wireMockServer.stop();
    }

    @Before
    public void setUp() {
        Map<String, String> joinedMap = new HashMap<>();
        joinedMap.putAll(STASH_CONFIG_MAP);
        joinedMap.putAll(STASH_PATCHSET_MAP);
        new ConfigurationSetup().setUp(joinedMap);
        stashFacade = new StashFacadeBuilder().build();
        startServerWithDefaultKeystore();
    }

    public void startServerWithDefaultKeystore() {
        //this is wiremock's default keystore
        WireMockConfiguration config = wireMockConfig().port(PORT).httpsPort(HTTPS_PORT);
        wireMockServer = new WireMockServer(config);
        wireMockServer.start();
        WireMock.configure();
        httpClient = HttpClientFactory.createClient();
    }

    @Test
    public void shouldGetChangeInfo() throws Exception {
        configureFor("localhost", PORT);
        String changesUrl = "/rest/api/1.0/projects/mykey/repos/myproject/pull-requests/12/changes";
        stubFor(get(urlEqualTo(changesUrl))
                .withHeader("Authorization", equalTo("Basic dXNlcjpwYXNz"))
                .willReturn(aResponse()
                        .withStatus(200)
                        .withHeader("Content-Type", "application/json")
                        .withBody(IOUtils.toString(getClass().getResourceAsStream("/json/stash-changes.json")))));

        List<ReviewFile> files = stashFacade.listFiles();
        assertThat(files).hasSize(4);
    }

    private String url(String path) {
        return String.format("https://localhost:%d%s", HTTPS_PORT, path);
    }

    private void getAndAssertUnderlyingExceptionInstanceClass(String url, Class<?> expectedClass) {
        boolean thrown = false;
        try {
            contentFor(url);
        } catch (Exception e) {
            Throwable cause = e.getCause();
            if (cause != null) {
                Assert.assertThat(e.getCause(), instanceOf(expectedClass));
            } else {
                Assert.assertThat(e, instanceOf(expectedClass));
            }

            thrown = true;
        }

        assertTrue("No exception was thrown", thrown);
    }

    private String contentFor(String url) throws Exception {
        HttpGet get = new HttpGet(url);
        HttpResponse response = httpClient.execute(get);
        String content = EntityUtils.toString(response.getEntity());
        return content;
    }
}

@@ -78,509 +78,111 @@
 ock.
-WireMockServer;%0Aimport com.github.tomakehurst.wiremock.client.WireMock;%0Aimport com.github.tomakehurst.wiremock.core.WireMockConfiguration;%0Aimport com.github.tomakehurst.wiremock.http.HttpClientFactory;%0Aimport com.google.common.collect.ImmutableMap;%0Aimport org.apache.commons.io.IOUtils;%0Aimport org.apache.http.HttpResponse;%0Aimport org.apache.http.client.HttpClient;%0Aimport org.apache.http.client.methods.HttpGet;%0Aimport org.apache.http.util.EntityUtils;%0Aimport org.junit.After;%0Aimport org.junit.Assert
+junit.WireMockRule;%0Aimport com.google.common.collect.ImmutableMap;%0Aimport org.apache.commons.io.IOUtils
 ;%0Aim
@@ -204,16 +204,39 @@
 Before;%0A
+import org.junit.Rule;%0A
 import o
@@ -505,245 +505,50 @@
 tic 
-com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;%0Aimport static junit.framework.Assert.assertTrue;%0Aimport static org.assertj.core.api.Assertions.assertThat;%0Aimport static org.hamcrest.core.IsInstanceOf.instanceOf
+org.assertj.core.api.Assertions.assertThat
 ;%0A%0Ap
@@ -1232,27 +1232,37 @@
 Facade;%0A
-    private
+%0A    @Rule%0A    public
  WireMoc
@@ -1262,22 +1262,20 @@
 WireMock
-Server
+Rule
  wireMoc
@@ -1279,135 +1279,50 @@
 Mock
-Server;%0A    private HttpClient httpClient;%0A%0A%0A    @After%0A    public void serverShutdown() %7B%0A        wireMockServer.stop();%0A    %7D
+Rule = new WireMockRule(PORT, HTTPS_PORT);
 %0A%0A  
@@ -1615,414 +1615,8 @@
 ();%0A
-        startServerWithDefaultKeystore();%0A    %7D%0A%0A    public void startServerWithDefaultKeystore() %7B%0A        //this is wiremock's default keystore%0A        WireMockConfiguration config = wireMockConfig().port(PORT).httpsPort(HTTPS_PORT);%0A        wireMockServer = new WireMockServer(config);%0A        wireMockServer.start();%0A        WireMock.configure();%0A        httpClient = HttpClientFactory.createClient();%0A
     
@@ -2321,945 +2321,7 @@
    %7D
-%0A%0A    private String url(String path) %7B%0A        return String.format(%22https://localhost:%25d%25s%22, HTTPS_PORT, path);%0A    %7D%0A%0A    private void getAndAssertUnderlyingExceptionInstanceClass(String url, Class%3C?%3E expectedClass) %7B%0A        boolean thrown = false;%0A        try %7B%0A            contentFor(url);%0A        %7D catch (Exception e) %7B%0A            Throwable cause = e.getCause();%0A            if (cause != null) %7B%0A                Assert.assertThat(e.getCause(), instanceOf(expectedClass));%0A            %7D else %7B%0A                Assert.assertThat(e, instanceOf(expectedClass));%0A            %7D%0A%0A            thrown = true;%0A        %7D%0A%0A        assertTrue(%22No exception was thrown%22, thrown);%0A    %7D%0A%0A    private String contentFor(String url) throws Exception %7B%0A        HttpGet get = new HttpGet(url);%0A        HttpResponse response = httpClient.execute(get);%0A        String content = EntityUtils.toString(response.getEntity());%0A        return content;%0A    %7D
 %0A%7D%0A

Use wiremock rule for testing