package com.deutscheboerse.risk.dave;

import com.deutscheboerse.risk.dave.model.AccountMarginModel;
import io.vertx.core.DeploymentOptions;
import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.mongo.MongoClient;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.IOException;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicLong;

@RunWith(VertxUnitRunner.class)
public class MainVerticleIT {
    private static final int BROKER_PORT = Integer.getInteger("cil.tcpport", 5672);
    private static final String DB_NAME = "DAVe-Test" + UUID.randomUUID().getLeastSignificantBits();
    private static final int DB_PORT =  Integer.getInteger("mongodb.port", 27017);
    private static Vertx vertx;
    private static MongoClient mongoClient;

    @BeforeClass
    public static void setUp(TestContext context) {
        MainVerticleIT.vertx = Vertx.vertx();
        JsonObject brokerConfig = new JsonObject()
                .put("port", BROKER_PORT)
                .put("listeners", new JsonObject()
                        .put("accountMargin", "broadcast.PRISMA_BRIDGE.PRISMA_TTSAVEAccountMargin"));
        JsonObject mongoConfig = new JsonObject()
                .put("dbName", MainVerticleIT.DB_NAME)
                .put("connectionUrl", "mongodb://localhost:" + MainVerticleIT.DB_PORT);
        JsonObject config = new JsonObject()
                .put("broker", brokerConfig)
                .put("mongo", mongoConfig);
        DeploymentOptions options = new DeploymentOptions().setConfig(config);
        MainVerticleIT.vertx.deployVerticle(MainVerticle.class.getName(), options, context.asyncAssertSuccess());
        MainVerticleIT.createMongoClient();
    }

    private static void createMongoClient() {
        JsonObject mongoConfig = new JsonObject()
                .put("db_name", MainVerticleIT.DB_NAME)
                .put("connection_string", "mongodb://localhost:" + MainVerticleIT.DB_PORT);
        MainVerticleIT.mongoClient = MongoClient.createShared(MainVerticleIT.vertx, mongoConfig);
    }

    @Test
    public void testFullChain(TestContext context) throws IOException, InterruptedException {
        final BrokerFiller brokerFiller = new BrokerFiller(MainVerticleIT.vertx);
        final Async asyncSend = context.async();
        Future<?> brokerFillerFuture = brokerFiller.setUp();
        brokerFillerFuture.setHandler(ar -> {
            if (ar.succeeded()) {
                asyncSend.complete();
            } else {
                context.fail(brokerFillerFuture.cause());
            }
        });
        asyncSend.awaitSuccess(5000);
        this.testCountInCollection(context, AccountMarginModel.MONGO_HISTORY_COLLECTION, 1704);
    }

    private void testCountInCollection(TestContext  context, String collection, long count) {
        AtomicLong currentCount = new AtomicLong();
        int tries = 0;
        while (currentCount.get() != count && tries < 10) {
            Async asyncHistoryCount = context.async();
            MainVerticleIT.mongoClient.count(collection, new JsonObject(), ar -> {
                if (ar.succeeded()) {
                    currentCount.set(ar.result());
                    if (currentCount.get() == count) {
                        asyncHistoryCount.complete();
                    }
                } else {
                    context.fail(ar.cause());
                }
            });
            try {
                asyncHistoryCount.await(1000);
            } catch (Exception ignored) {
                asyncHistoryCount.complete();
            }
            tries++;
        }
        context.assertEquals(count, currentCount.get());
    }

    @AfterClass
    public static void tearDown(TestContext context) {
        MainVerticleIT.vertx.close(context.asyncAssertSuccess());
    }
}

@@ -1119,24 +1119,482 @@
 tx.vertx();%0A
+        MainVerticleIT.createMongoClient();%0A    %7D%0A%0A    private static void createMongoClient() %7B%0A        JsonObject mongoConfig = new JsonObject()%0A                .put(%22db_name%22, MainVerticleIT.DB_NAME)%0A                .put(%22connection_string%22, %22mongodb://localhost:%22 + MainVerticleIT.DB_PORT);%0A        MainVerticleIT.mongoClient = MongoClient.createShared(MainVerticleIT.vertx, mongoConfig);%0A    %7D%0A%0A    private DeploymentOptions createDeploymentOptions() %7B%0A
         Json
@@ -2245,617 +2245,311 @@
     
-MainVerticleIT.vertx.deployVerticle(MainVerticle.class.getName(), options, context.asyncAssertSuccess())
+return options
 ;%0A    
+%7D%0A%0A
     
-MainVerticleIT.createMongoClient();%0A    %7D%0A%0A    private static void createMongoClient() %7B%0A        JsonObject mongoConfig = new JsonObject()%0A                .put(%22db_name%22, MainVerticleIT.DB_NAME)%0A                .put(%22connection_string%22, %22mongodb://localhost:%22 + MainVerticleIT.DB_PORT);%0A        MainVerticleIT.mongoClient = MongoClient.createShared(MainVerticleIT.vertx, mongoConfig);%0A    %7D%0A%0A    @Test%0A    public void testFullChain(TestContext context) throws IOException, InterruptedException %7B
+@Test%0A    public void testFullChain(TestContext context) throws IOException, InterruptedException %7B%0A        DeploymentOptions options = createDeploymentOptions();%0A        MainVerticleIT.vertx.deployVerticle(MainVerticle.class.getName(), options, context.asyncAssertSuccess());
 %0A   
@@ -3093,32 +3093,370 @@
 , 1704);%0A    %7D%0A%0A
+    @Test%0A    public void testFailedDeployment(TestContext context) %7B%0A        DeploymentOptions options = createDeploymentOptions();%0A        options.getConfig().getJsonObject(%22broker%22).put(%22hostname%22, %22nonexisting%22);%0A        MainVerticleIT.vertx.deployVerticle(MainVerticle.class.getName(), options, context.asyncAssertFailure());%0A    %7D%0A%0A
     private void

Test for failure in deploy of AMQPVerticle -> MainVerticle