// Path: qbit/core/src/main/java/io/advantageous/qbit/reactive/Callback.java
// public interface Callback<T> extends io.advantageous.reakt.CallbackHandler<T> {
// 
// 
//     /**
//      * Client View (client of the service)
//      * Called when there is an error
//      *
//      * @param error error
//      */
//     default void onError(final Throwable error) {
// 
//         LoggerFactory.getLogger(Callback.class)
//                 .error(error.getMessage(), error);
// 
//     }
// 
//     /**
//      * Performs this operation on the given argument.
//      *
//      * @param t the input argument
//      */
//     void accept(T t);
// 
// 
//     @Override
//     default void onResult(Result<T> result) {
//         if (result.failure()) {
//             onError(result.cause());
//         } else {
//             accept(result.get());
//         }
//     }
// 
// 
//     /**
//      * Called if there is a timeout.
//      * <p>
//      * This will be taken out in Reakt 3.0 (and QBit 2.0).
//      * Use reject instead.
//      */
//     default void onTimeout() {
//     }
// 
// 
//     /**
//      * Service View (service)
//      * Return an error message
//      * alias for reject.
//      * <p>
//      * This will be taken out in Reakt 3.0 (and QBit 2.0).
//      * Use reject instead.
//      *
//      * @param error error
//      */
//     @Deprecated
//     @SuppressWarnings("deprecated")
//     default void returnError(final String error) {
//         reject(error);
//     }
// 
// 
//     /**
//      * Service View (service)
//      * alias for reply
//      * <p>
//      * This will be taken out in Reakt 3.0 (and QBit 2.0).
//      * Use resolve or reply instead.
//      *
//      * @param thisReturn the value to return.
//      */
//     @Deprecated
//     @SuppressWarnings("deprecated")
//     default void returnThis(T thisReturn) {
//         resolve(thisReturn);
//     }
// 
// 
// }


import io.advantageous.qbit.client.Client;
import io.advantageous.qbit.client.ClientBuilder;
import io.advantageous.qbit.reactive.Callback;
import io.advantageous.qbit.server.EndpointServerBuilder;
import io.advantageous.qbit.server.ServiceEndpointServer;
import io.advantageous.qbit.service.ServiceProxyUtils;
import io.advantageous.qbit.util.PortUtils;
import io.advantageous.reakt.promise.Promise;
import io.advantageous.reakt.promise.Promises;
import org.junit.Test;
import java.net.ConnectException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import static org.junit.Assert.*;
        final Client client = ClientBuilder.clientBuilder().setPort(port).setHost("localhost").build().startClient();

        final EmployeeService employeeService = client.createProxy(EmployeeService.class, "employeeserviceimpl");

        ServiceProxyUtils.flushServiceProxy(employeeService);


        AtomicLong counter = new AtomicLong();
        final CountDownLatch latch = new CountDownLatch(20);

        for (int index = 0; index < 20; index++) {
            final AtomicReference<Employee> ref = new AtomicReference<>();
            employeeService.addEmployee(employee -> {
                ref.set(employee);
                System.out.println(ref.get());
                counter.incrementAndGet();
                latch.countDown();
            }, new Employee("rick"));

        }


        latch.await(2, TimeUnit.SECONDS);
        assertEquals(20, counter.get());


        serviceEndpointServer.stop();
    }

    interface EmployeeService {
// Path: qbit/core/src/main/java/io/advantageous/qbit/reactive/Callback.java
// public interface Callback<T> extends io.advantageous.reakt.CallbackHandler<T> {
// 
// 
//     /**
//      * Client View (client of the service)
//      * Called when there is an error
//      *
//      * @param error error
//      */
//     default void onError(final Throwable error) {
// 
//         LoggerFactory.getLogger(Callback.class)
//                 .error(error.getMessage(), error);
// 
//     }
// 
//     /**
//      * Performs this operation on the given argument.
//      *
//      * @param t the input argument
//      */
//     void accept(T t);
// 
// 
//     @Override
//     default void onResult(Result<T> result) {
//         if (result.failure()) {
//             onError(result.cause());
//         } else {
//             accept(result.get());
//         }
//     }
// 
// 
//     /**
//      * Called if there is a timeout.
//      * <p>
//      * This will be taken out in Reakt 3.0 (and QBit 2.0).
//      * Use reject instead.
//      */
//     default void onTimeout() {
//     }
// 
// 
//     /**
//      * Service View (service)
//      * Return an error message
//      * alias for reject.
//      * <p>
//      * This will be taken out in Reakt 3.0 (and QBit 2.0).
//      * Use reject instead.
//      *
//      * @param error error
//      */
//     @Deprecated
//     @SuppressWarnings("deprecated")
//     default void returnError(final String error) {
//         reject(error);
//     }
// 
// 
//     /**
//      * Service View (service)
//      * alias for reply
//      * <p>
//      * This will be taken out in Reakt 3.0 (and QBit 2.0).
//      * Use resolve or reply instead.
//      *
//      * @param thisReturn the value to return.
//      */
//     @Deprecated
//     @SuppressWarnings("deprecated")
//     default void returnThis(T thisReturn) {
//         resolve(thisReturn);
//     }
// 
// 
// }


// Path: qbit/vertx/src/test/java/io/advantageous/qbit/vertx/http/websocket/WebSocketProxy.java
import io.advantageous.qbit.client.Client;
import io.advantageous.qbit.client.ClientBuilder;
import io.advantageous.qbit.reactive.Callback;
import io.advantageous.qbit.server.EndpointServerBuilder;
import io.advantageous.qbit.server.ServiceEndpointServer;
import io.advantageous.qbit.service.ServiceProxyUtils;
import io.advantageous.qbit.util.PortUtils;
import io.advantageous.reakt.promise.Promise;
import io.advantageous.reakt.promise.Promises;
import org.junit.Test;
import java.net.ConnectException;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import static org.junit.Assert.*;

        final Client client = ClientBuilder.clientBuilder().setPort(port).setHost("localhost").build().startClient();

        final EmployeeService employeeService = client.createProxy(EmployeeService.class, "employeeserviceimpl");

        ServiceProxyUtils.flushServiceProxy(employeeService);


        AtomicLong counter = new AtomicLong();
        final CountDownLatch latch = new CountDownLatch(20);

        for (int index = 0; index < 20; index++) {
            final AtomicReference<Employee> ref = new AtomicReference<>();
            employeeService.addEmployee(employee -> {
                ref.set(employee);
                System.out.println(ref.get());
                counter.incrementAndGet();
                latch.countDown();
            }, new Employee("rick"));

        }


        latch.await(2, TimeUnit.SECONDS);
        assertEquals(20, counter.get());


        serviceEndpointServer.stop();
    }

    interface EmployeeService {
        void addEmployee(Callback<Employee> callback, Employee e);