/*
 * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
 * or more contributor license agreements. Licensed under the Elastic License;
 * you may not use this file except in compliance with the Elastic License.
 */
package org.elasticsearch.watcher.support.http;

import com.carrotsearch.randomizedtesting.annotations.Repeat;
import com.squareup.okhttp.mockwebserver.MockResponse;
import com.squareup.okhttp.mockwebserver.MockWebServer;
import com.squareup.okhttp.mockwebserver.RecordedRequest;
import org.elasticsearch.common.base.Charsets;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.settings.ImmutableSettings;
import org.elasticsearch.test.ElasticsearchTestCase;
import org.elasticsearch.watcher.support.http.auth.BasicAuth;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.hamcrest.Matchers.equalTo;

/**
 */
public class HttpClientTest extends ElasticsearchTestCase {

    private MockWebServer webServer;
    private HttpClient httpClient;

    @Before
    public void init() throws Exception {
        webServer = new MockWebServer();
        webServer.start(9200);
        httpClient = new HttpClient(ImmutableSettings.EMPTY);
    }

    @After
    public void after() throws Exception {
        webServer.shutdown();
    }

    @Test
    @Repeat(iterations = 10)
    public void testBasics() throws Exception {
        int responseCode = randomIntBetween(200, 203);
        String body = randomAsciiOfLengthBetween(2, 8096);
        webServer.enqueue(new MockResponse().setResponseCode(responseCode).setBody(body));


        HttpRequest request = new HttpRequest();
        request.method(HttpMethod.POST);
        request.host("localhost");
        request.port(9200);
        request.path("/" + randomAsciiOfLength(5));
        String paramKey;
        String paramValue;
        request.params(MapBuilder.<String, String>newMapBuilder()
                .put(paramKey = randomAsciiOfLength(3), paramValue = randomAsciiOfLength(3))
                .map());
        String headerKey;
        String headerValue;
        request.headers(MapBuilder.<String, String>newMapBuilder()
                .put(headerKey = randomAsciiOfLength(3), headerValue = randomAsciiOfLength(3))
                .map());
        request.body(randomAsciiOfLength(5));
        HttpResponse response = httpClient.execute(request);
        RecordedRequest recordedRequest = webServer.takeRequest();

        assertThat(response.status(), equalTo(responseCode));
        assertThat(new String(response.body(), Charsets.UTF_8), equalTo(body));
        assertThat(webServer.getRequestCount(), equalTo(1));
        assertThat(recordedRequest.getBody().readString(Charsets.UTF_8), equalTo(request.body()));
        assertThat(recordedRequest.getPath().split("\\?")[0], equalTo(request.path()));
        assertThat(recordedRequest.getPath().split("\\?")[1], equalTo(paramKey + "=" + paramValue));
        assertThat(recordedRequest.getHeader(headerKey), equalTo(headerValue));
    }

    @Test
    public void testBasicAuth() throws Exception {
        webServer.enqueue(new MockResponse().setResponseCode(200).setBody("body"));
        HttpRequest request = new HttpRequest();
        request.method(HttpMethod.POST);
        request.host("localhost");
        request.port(9200);
        request.path("/test");
        request.auth(new BasicAuth("user", "pass"));
        request.body("body");
        HttpResponse response = httpClient.execute(request);
        assertThat(response.status(), equalTo(200));
        assertThat(new String(response.body(), Charsets.UTF_8), equalTo("body"));
        RecordedRequest recordedRequest = webServer.takeRequest();
        assertThat(recordedRequest.getHeader("Authorization"), equalTo("Basic dXNlcjpwYXNz"));
    }

}

@@ -515,16 +515,65 @@
 equest;%0A
+import org.elasticsearch.ElasticsearchException;%0A
 import o
@@ -611,16 +611,16 @@
 arsets;%0A
-
 import o
@@ -911,16 +911,48 @@
 .Test;%0A%0A
+import java.net.BindException;%0A%0A
 import s
@@ -1131,16 +1131,49 @@
 lient;%0A%0A
+    private int webPort = 9200;%0A%0A
     @Bef
@@ -1272,29 +1272,430 @@
    w
-ebServer.start(9200);
+hile (webPort %3C 9300) %7B%0A            try %7B%0A                webServer.start(webPort);%0A                break;%0A            %7D catch (BindException be) %7B%0A                logger.warn(%22port %5B%7B%7D%5D was already in use trying next port%22, webPort);%0A                ++webPort;%0A            %7D%0A        %7D%0A        if (webPort == 9300) %7B%0A            throw new ElasticsearchException(%22unable to find open port between 9200 and 9300%22);%0A        %7D
 %0A   
@@ -2283,36 +2283,39 @@
    request.port(
-9200
+webPort
 );%0A        reque
@@ -3874,20 +3874,23 @@
 st.port(
-9200
+webPort
 );%0A     

Fix HttpClientTest