/*
 * Knot.x - Reactive microservice assembler - Http Service Adapter
 *
 * Copyright (C) 2016 Cognifide Limited
 *
 * 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.cognifide.knotx.core.serviceadapter.http;

import com.cognifide.knotx.dataobjects.ClientResponse;
import com.cognifide.knotx.junit.FileReader;
import com.cognifide.knotx.junit.KnotxConfiguration;
import com.cognifide.knotx.junit.Logback;
import com.cognifide.knotx.junit.TestVertxDeployer;

import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.RuleChain;
import org.junit.runner.RunWith;

import io.netty.handler.codec.http.HttpResponseStatus;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.RunTestOnContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import rx.Observable;
import rx.functions.Action1;

@RunWith(VertxUnitRunner.class)
public class HttpServiceAdapterTest {

  private final static String ADAPTER_ADDRESS = "knotx.core.http.service-adapter";

  //Test Runner Rule of Verts
  private RunTestOnContext vertx = new RunTestOnContext();

  //Test Runner Rule of Knotx
  private TestVertxDeployer knotx = new TestVertxDeployer(vertx);

  //Junit Rule, sets up logger, prepares verts, starts verticles according to the config (supplied in annotation of test method)
  @Rule
  public RuleChain chain = RuleChain.outerRule(new Logback()).around(vertx).around(knotx);

  @Test
  @KnotxConfiguration("knotx-service-adapter-http-test.json")
  public void callNonExistingService_expectBadRequestResponse(TestContext context) {
    callAdapterServiceWithAssertions(context, "not/existing/service/address", HttpMethod.GET, httpResponseWrapper ->
        context.assertTrue(httpResponseWrapper.statusCode().equals(HttpResponseStatus.BAD_REQUEST)));
  }


  @Test
  @KnotxConfiguration("knotx-service-adapter-http-test.json")
  public void callExistingService_expectOKResponseWithServiceDataProvidedByService1(TestContext context) throws Exception {
    final String expected = FileReader.readText("first-response.json");

    callAdapterServiceWithAssertions(context, "/service/mock/first.json", HttpMethod.GET, httpResponseWrapper -> {
      context.assertTrue(httpResponseWrapper.statusCode().equals(HttpResponseStatus.OK));
      context.assertTrue(httpResponseWrapper.headers().isEmpty());

        JsonObject serviceResponse = new JsonObject(httpResponseWrapper.body().toString());
      JsonObject expectedResponse = new JsonObject(expected);
        context.assertEquals(serviceResponse, expectedResponse);
    });
  }

  private void callAdapterServiceWithAssertions(TestContext context, String servicePath, HttpMethod method, Action1<ClientResponse> testFunction) {
    JsonObject message = payloadMessage(servicePath);
    Async async = context.async();

    vertx.vertx().eventBus().<JsonObject>send(ADAPTER_ADDRESS, message, ar -> {
      if (ar.succeeded()) {
        Observable
            .just(new ClientResponse(ar.result().body()))
            .doOnNext(testFunction);
      } else {
        context.fail(ar.cause());
      }
      async.complete();
    });
  }

  private JsonObject payloadMessage(String servicePath) {
    return new JsonObject()
        .put("params", new JsonObject()
            .put("path", servicePath))
        .put("clientRequest", new JsonObject());
  }

}

@@ -1145,46 +1145,8 @@
 us;%0A
-import io.vertx.core.http.HttpMethod;%0A
 impo
@@ -2205,48 +2205,39 @@
 ss%22,
- HttpMethod.GET, httpResponseWrapper -%3E%0A
+%0A        clientResponse -%3E %7B%0A  
     
@@ -2255,36 +2255,38 @@
 .assertTrue(
-http
+client
 Response
 Wrapper.stat
@@ -2265,39 +2265,32 @@
 e(clientResponse
-Wrapper
 .statusCode().eq
@@ -2317,19 +2317,91 @@
 tus.
-BAD_REQUEST
+INTERNAL_SERVER_ERROR));%0A        %7D,%0A        error -%3E context.fail(error.getMessage(
 )));
@@ -2751,37 +2751,31 @@
 on%22,
- HttpMethod.GET, http
+%0A        client
 Response
 Wrap
@@ -2774,21 +2774,18 @@
 onse
-Wrapper
  -%3E %7B%0A
+    
     
@@ -2801,36 +2801,38 @@
 .assertTrue(
-http
+client
 Response
 Wrapper.stat
@@ -2819,23 +2819,16 @@
 Response
-Wrapper
 .statusC
@@ -2867,24 +2867,28 @@
 OK));%0A      
+    
 context.asse
@@ -2894,28 +2894,30 @@
 ertTrue(
-http
+client
 Response
 Wrapper.
@@ -2908,23 +2908,16 @@
 Response
-Wrapper
 .headers
@@ -2928,24 +2928,26 @@
 sEmpty());%0A%0A
+  
         Json
@@ -2990,20 +2990,22 @@
 ect(
-http
+client
 Response
 Wrap
@@ -3004,15 +3004,8 @@
 onse
-Wrapper
 .bod
@@ -3023,24 +3023,28 @@
 g());%0A      
+   
+ 
 JsonObject e
@@ -3087,16 +3087,18 @@
 ected);%0A
+  
         
@@ -3154,25 +3154,80 @@
 ponse);%0A    
+  
-%7D
+  %7D,%0A        error -%3E context.fail(error.getMessage())
 );%0A  %7D%0A%0A  pr
@@ -3314,27 +3314,8 @@
 ath,
- HttpMethod method,
  Act
@@ -3335,28 +3335,53 @@
 sponse%3E 
-testFunction
+onSuccess, Action1%3CThrowable%3E onError
 ) %7B%0A    
@@ -3668,29 +3668,115 @@
    .
-doOnNext(testFunction
+subscribe(%0A                onSuccess,%0A                onError,%0A                async::complete%0A            
 );%0A 
@@ -3835,32 +3835,8 @@
   %7D%0A
-      async.complete();%0A
     

fix HttpServiceAdapterTest