// Path: jagnet-core/src/main/java/org/gillius/jagnet/netty/NettyClient.java
// public class NettyClient implements Client {
// 	private static final Logger log = LoggerFactory.getLogger(NettyClient.class);
// 
// 	private final ConnectionParams params;
// 
// 	private NettyConnection connection;
// 	private final CompletableFuture<Connection> connFuture = new CompletableFuture<>();
// 	private EventLoopGroup group;
// 
// 	public NettyClient(ConnectionParams params) {
// 		this.params = params.clone();
// 	}
// 
// 	@Override
// 	public void close() {
// 		if (connection != null)
// 			connection.close();
// 		if (group != null)
// 			group.shutdownGracefully();
// 		connection = null;
// 		group = null;
// 	}
// 
// 	public void start() {
// 		//TODO: prevent starting more than once (race conditions on close/failure)
// 
// 		Kryo kryo = KryoBuilder.build(params.getMessageTypes());
// 
// 		group = new NioEventLoopGroup();
// 		Bootstrap b = new Bootstrap();
// 		b.group(group)
// 		 .channel(NioSocketChannel.class)
// 		 .option(ChannelOption.TCP_NODELAY, true)
// 		 .handler(new ChannelInitializer<SocketChannel>() {
// 			 @Override
// 			 public void initChannel(SocketChannel ch) throws Exception {
// 				 connection = new NettyConnection(ch);
// 				 connection.getCloseFuture().thenRun(NettyClient.this::close);
// 				 if (params.getProtocol() == Protocol.WS)
// 					 NettyUtils.configurePipelineForWebsocketClient(ch, params);
// 
// 				 NettyUtils.setupClientPipeline(ch, params.getProxyTag(), kryo, params, getConnectionStateListener());
// 			 }
// 		 });
// 
// 		// Start the client.
// 		b.connect(params.getRemoteAddress(), params.getLocalAddress()).addListener(future -> {
// 			if (!future.isSuccess()) {
// 				connFuture.completeExceptionally(future.cause());
// 				close();
// 			}
// 		});
// 	}
// 
// 	@Override
// 	public CompletableFuture<Connection> getConnection() {
// 		return connFuture;
// 	}
// 
// 	private ConnectionStateListener getConnectionStateListener() {
// 		return new ConnectionStateListener() {
// 			@Override
// 			public void onConnected(ConnectionListenerContext ctx) {
// 				connFuture.complete(connection);
// 			}
// 		};
// 	}
// }
// 
// Path: jagnet-examples/src/main/java/org/gillius/jagnet/examples/ExampleUtil.java
// public static String getUri(String args[]) {
// 	if (args.length > 1) {
// 		return args[0];
// 	} else {
// 		String uri = "tcp://localhost:54555";
// 		//alternative uri = "proxy+ws://localhost:56238/websocket?ServerExample"
// 		log.info("Using default URI parameter {}", uri);
// 		return uri;
// 	}
// }


import org.gillius.jagnet.*;
import org.gillius.jagnet.netty.NettyClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.gillius.jagnet.examples.ExampleUtil.getUri;
package org.gillius.jagnet.examples;



public class ClientExample {
	private static final Logger log = LoggerFactory.getLogger(ClientExample.class);

	public static void main(String[] args) throws Exception {
		ConditionConnectionListener listener = new ConditionConnectionListener();

		ConnectionParams params = new ConnectionParams()
				.setByURI(getUri(args), false)
				.setListener(listener);

		Client client = new NettyClient(params);
		TimeSync sync = new TimeSync();

		client.start();
		Connection conn = client.getConnection().get();

		for (int i=0; i<3; ++i) {
			//TODO: currently we "sendReliable" but the standard listener always replies with "sendFast"
// Path: jagnet-core/src/main/java/org/gillius/jagnet/netty/NettyClient.java
// public class NettyClient implements Client {
// 	private static final Logger log = LoggerFactory.getLogger(NettyClient.class);
// 
// 	private final ConnectionParams params;
// 
// 	private NettyConnection connection;
// 	private final CompletableFuture<Connection> connFuture = new CompletableFuture<>();
// 	private EventLoopGroup group;
// 
// 	public NettyClient(ConnectionParams params) {
// 		this.params = params.clone();
// 	}
// 
// 	@Override
// 	public void close() {
// 		if (connection != null)
// 			connection.close();
// 		if (group != null)
// 			group.shutdownGracefully();
// 		connection = null;
// 		group = null;
// 	}
// 
// 	public void start() {
// 		//TODO: prevent starting more than once (race conditions on close/failure)
// 
// 		Kryo kryo = KryoBuilder.build(params.getMessageTypes());
// 
// 		group = new NioEventLoopGroup();
// 		Bootstrap b = new Bootstrap();
// 		b.group(group)
// 		 .channel(NioSocketChannel.class)
// 		 .option(ChannelOption.TCP_NODELAY, true)
// 		 .handler(new ChannelInitializer<SocketChannel>() {
// 			 @Override
// 			 public void initChannel(SocketChannel ch) throws Exception {
// 				 connection = new NettyConnection(ch);
// 				 connection.getCloseFuture().thenRun(NettyClient.this::close);
// 				 if (params.getProtocol() == Protocol.WS)
// 					 NettyUtils.configurePipelineForWebsocketClient(ch, params);
// 
// 				 NettyUtils.setupClientPipeline(ch, params.getProxyTag(), kryo, params, getConnectionStateListener());
// 			 }
// 		 });
// 
// 		// Start the client.
// 		b.connect(params.getRemoteAddress(), params.getLocalAddress()).addListener(future -> {
// 			if (!future.isSuccess()) {
// 				connFuture.completeExceptionally(future.cause());
// 				close();
// 			}
// 		});
// 	}
// 
// 	@Override
// 	public CompletableFuture<Connection> getConnection() {
// 		return connFuture;
// 	}
// 
// 	private ConnectionStateListener getConnectionStateListener() {
// 		return new ConnectionStateListener() {
// 			@Override
// 			public void onConnected(ConnectionListenerContext ctx) {
// 				connFuture.complete(connection);
// 			}
// 		};
// 	}
// }
// 
// Path: jagnet-examples/src/main/java/org/gillius/jagnet/examples/ExampleUtil.java
// public static String getUri(String args[]) {
// 	if (args.length > 1) {
// 		return args[0];
// 	} else {
// 		String uri = "tcp://localhost:54555";
// 		//alternative uri = "proxy+ws://localhost:56238/websocket?ServerExample"
// 		log.info("Using default URI parameter {}", uri);
// 		return uri;
// 	}
// }


// Path: jagnet-examples/src/main/java/org/gillius/jagnet/examples/ClientExample.java
import org.gillius.jagnet.*;
import org.gillius.jagnet.netty.NettyClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.gillius.jagnet.examples.ExampleUtil.getUri;

package org.gillius.jagnet.examples;



public class ClientExample {
	private static final Logger log = LoggerFactory.getLogger(ClientExample.class);

	public static void main(String[] args) throws Exception {
		ConditionConnectionListener listener = new ConditionConnectionListener();

		ConnectionParams params = new ConnectionParams()
				.setByURI(getUri(args), false)
				.setListener(listener);

		Client client = new NettyClient(params);
		TimeSync sync = new TimeSync();

		client.start();
		Connection conn = client.getConnection().get();

		for (int i=0; i<3; ++i) {
			//TODO: currently we "sendReliable" but the standard listener always replies with "sendFast"
			TimeSyncResponse response = listener.sendReliableAndReceive(sync.send(), TimeSyncResponse.class).join();