/*-
 * -\-\-
 * Spotify Apollo okhttp Client Module
 * --
 * Copyright (C) 2013 - 2021 Spotify AB
 * --
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * -/-/-
 */

package com.spotify.apollo.http.client;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.isA;
import static org.mockito.Mockito.when;

import com.codahale.metrics.Histogram;
import com.codahale.metrics.Meter;
import com.spotify.apollo.Request;
import com.spotify.apollo.Response;
import com.spotify.apollo.Status;
import com.spotify.apollo.environment.IncomingRequestAwareClient;
import com.spotify.metrics.core.MetricId;
import com.spotify.metrics.core.SemanticMetricRegistry;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.Strict.class)
public class MetricsHttpClientTest {

  @Mock private IncomingRequestAwareClient client;

  @Mock private SemanticMetricRegistry semanticMetricRegistry;

  @Mock private Meter meter;

  @Mock private Histogram histogram;

  @InjectMocks private MetricsHttpClient sut;

  private Request standardRequest = Request.forUri("http://www.spotify.com");

  @Rule public ExpectedException thrown = ExpectedException.none();

  @Test
  public void testNonHttpRequestSentAsStandard() throws ExecutionException, InterruptedException {

    final Request request = Request.forUri("ftp://a-thing.com");
    when(client.send(request, Optional.empty()))
        .thenReturn(CompletableFuture.completedFuture(Response.ok()));
    final Response response = sut.send(request, Optional.empty()).toCompletableFuture().get();
    assertThat(response.status(), is(Status.OK));
  }

  @Test
  public void testHttpRequestReturnsCompletionStage()
      throws ExecutionException, InterruptedException {
    when(semanticMetricRegistry.meter(
            MetricId.build()
                .tagged("what", "message-rate")
                .tagged("status-code", "200")
                .tagged("target-host", "www.spotify.com")
                .tagged("protocol", "http/https")
                .tagged("unit", "request")))
        .thenReturn(meter);
    when(semanticMetricRegistry.histogram(
            MetricId.build()
                .tagged("what", "request-latency")
                .tagged("unit", "ms")
                .tagged("protocol", "http/https")
                .tagged("target-host", "www.spotify.com")))
        .thenReturn(histogram);
    when(client.send(standardRequest, Optional.empty()))
        .thenReturn(CompletableFuture.completedFuture(Response.ok()));
    final Response response =
        sut.send(standardRequest, Optional.empty()).toCompletableFuture().get();
    assertThat(response.status(), is(Status.OK));
  }

  @Test
  public void testHttpRequestExceptionPath() throws ExecutionException, InterruptedException {
    when(semanticMetricRegistry.meter(
            MetricId.build()
                .tagged("what", "message-rate")
                .tagged("status-code", "EXCEPTION")
                .tagged("target-host", "www.spotify.com")
                .tagged("protocol", "http/https")
                .tagged("unit", "request")))
        .thenReturn(meter);
    when(semanticMetricRegistry.histogram(
            MetricId.build()
                .tagged("what", "request-latency")
                .tagged("unit", "ms")
                .tagged("protocol", "http/https")
                .tagged("target-host", "www.spotify.com")))
        .thenReturn(histogram);

    when(client.send(standardRequest, Optional.empty()))
        .thenReturn(
            CompletableFuture.supplyAsync(
                () -> {
                  throw new RuntimeException("failed");
                }));

    thrown.expectCause(isA(RuntimeException.class));
    thrown.expectMessage("failed");

    sut.send(standardRequest, Optional.empty()).toCompletableFuture().get();
  }
}

@@ -1346,32 +1346,81 @@
 utionException;%0A
+import okio.ByteString;%0Aimport org.junit.Before;%0A
 import org.junit
@@ -1426,16 +1426,16 @@
 t.Rule;%0A
-
 import o
@@ -1757,30 +1757,24 @@
  client;%0A%0A  
-@Mock 
 private Sema
@@ -1818,76 +1818,39 @@
 stry
-;%0A%0A  @Mock private Meter meter;%0A%0A  @Mock private Histogram histogram
+ = new SemanticMetricRegistry()
 ;%0A%0A 
@@ -2043,16 +2043,120 @@
 one();%0A%0A
+  @Before%0A  public void setUp() %7B%0A    sut = new MetricsHttpClient(client, semanticMetricRegistry);%0A  %7D%0A%0A
   @Test%0A
@@ -2450,32 +2450,44 @@
   final Response
+%3CByteString%3E
  response = sut.
@@ -2481,16 +2481,24 @@
 sponse =
+%0A       
  sut.sen
@@ -2732,654 +2732,8 @@
 n %7B%0A
-    when(semanticMetricRegistry.meter(%0A            MetricId.build()%0A                .tagged(%22what%22, %22message-rate%22)%0A                .tagged(%22status-code%22, %22200%22)%0A                .tagged(%22target-host%22, %22www.spotify.com%22)%0A                .tagged(%22protocol%22, %22http/https%22)%0A                .tagged(%22unit%22, %22request%22)))%0A        .thenReturn(meter);%0A    when(semanticMetricRegistry.histogram(%0A            MetricId.build()%0A                .tagged(%22what%22, %22request-latency%22)%0A                .tagged(%22unit%22, %22ms%22)%0A                .tagged(%22protocol%22, %22http/https%22)%0A                .tagged(%22target-host%22, %22www.spotify.com%22)))%0A        .thenReturn(histogram);%0A
     
@@ -2874,16 +2874,28 @@
 Response
+%3CByteString%3E
  respons
@@ -3034,32 +3034,32 @@
 );%0A  %7D%0A%0A  @Test%0A
+
   public void te
@@ -3141,661 +3141,8 @@
 n %7B%0A
-    when(semanticMetricRegistry.meter(%0A            MetricId.build()%0A                .tagged(%22what%22, %22message-rate%22)%0A                .tagged(%22status-code%22, %22EXCEPTION%22)%0A                .tagged(%22target-host%22, %22www.spotify.com%22)%0A                .tagged(%22protocol%22, %22http/https%22)%0A                .tagged(%22unit%22, %22request%22)))%0A        .thenReturn(meter);%0A    when(semanticMetricRegistry.histogram(%0A            MetricId.build()%0A                .tagged(%22what%22, %22request-latency%22)%0A                .tagged(%22unit%22, %22ms%22)%0A                .tagged(%22protocol%22, %22http/https%22)%0A                .tagged(%22target-host%22, %22www.spotify.com%22)))%0A        .thenReturn(histogram);%0A%0A
     

remove stubbing