package com.sf.vertx;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import io.vertx.core.Vertx;
import io.vertx.core.VertxOptions;
import io.vertx.core.eventbus.EventBus;
import io.vertx.core.eventbus.EventBusOptions;
import io.vertx.core.eventbus.MessageConsumer;
import io.vertx.ext.unit.Async;
import io.vertx.ext.unit.TestContext;
import io.vertx.ext.unit.junit.VertxUnitRunner;
import lombok.extern.slf4j.Slf4j;

@Slf4j
@RunWith(VertxUnitRunner.class)
public class TestEventBus {
	private Vertx vertx;

	@Before
	public void setUp(TestContext tc) {
		// 创建vertx服务
		vertx = Vertx.vertx(new VertxOptions().setWorkerPoolSize(100));
	}

	@After
	public void tearDown() {
		vertx.close();
	}

	/***
	 * 发布订阅
	 * 
	 * @param tc
	 */
	@Test
	public void testPublish(TestContext tc) {
		Async async = tc.async();
		EventBus eventBus = vertx.eventBus();
		MessageConsumer<String> consumer = eventBus.consumer("synAppCode");
		consumer.handler(message -> {
			System.out.println("consumer I have received a message: " + message.body());
			message.reply("how interesting!");
		});
		consumer.completionHandler(res -> {
			if (res.succeeded()) {
				System.out.println("The handler registration has reached all nodes");
			} else {
				System.out.println("Registration failed!");
			}
		});

		MessageConsumer<String> consumer1 = eventBus.consumer("synAppCode");
		consumer1.handler(message -> {
			System.out.println("consumer1 I have received a message: " + message.body());
			message.reply("how interesting!");
		});
		eventBus.publish("synAppCode", "hello world");
		// eventBus.publish("synAppCode", "hello world");

		eventBus.request("synAppCode", "Yay! Someone kicked a ball across a patch of grass", ar -> {
			if (ar.succeeded()) {
				System.out.println("Received reply: " + ar.result().body());
			}
		});
	}

	/***
	 * 点点发送 在对应地址上注册过的所有处理器中， 仅一个处理器能够接收到发送的消息。 这是一种点对点消息传递模式。 Vert.x
	 * 使用不严格的轮询算法来选择绑定的处理器。
	 * 
	 * @param tc
	 */
	@Test
	public void testSend(TestContext tc) {
		Async async = tc.async();
		EventBus eb = vertx.eventBus();
		MessageConsumer<String> consumer = eb.consumer("synAppCode");
		consumer.handler(message -> {
			System.out.println("consumer I have received a message: " + message.body());
		});
		consumer.completionHandler(res -> {
			if (res.succeeded()) {
				System.out.println("The handler registration has reached all nodes");
			} else {
				System.out.println("Registration failed!");
			}
		});

		MessageConsumer<String> consumer1 = eb.consumer("synAppCode");
		consumer1.handler(message -> {
			System.out.println("consumer1 I have received a message: " + message.body());
		});
		eb.send("synAppCode", "hello world");
	}

	@Test
	public void clusterConsumer(TestContext tc) {
		Async async = tc.async();
		VertxOptions options = new VertxOptions()
				.setEventBusOptions(new EventBusOptions().setClusterPublicHost("192.168.1.68").setClusterPublicPort(1));

		Vertx.clusteredVertx(options).onComplete(res -> {
			if (res.succeeded()) {
				Vertx vertx = res.result();
				EventBus eventBus = vertx.eventBus();
				MessageConsumer<String> consumer = eventBus.consumer("synAppCode");
				consumer.handler(message -> {
					System.out.println("consumer I have received a message: " + message.body());
				});
				consumer.completionHandler(resData -> {
					if (res.succeeded()) {
						System.out.println("The handler registration has reached all nodes");
					} else {
						System.out.println("Registration failed!");
					}
				});
				eventBus.publish("synAppCode", "hello world");
				System.out.println("We now have a clustered event bus: " + eventBus);
			} else {
				System.out.println("Failed: " + res.cause());
			}
		});
	}

	@Test
	public void clusterPublish(TestContext tc) {
		Async async = tc.async();
		VertxOptions options = new VertxOptions()
				.setEventBusOptions(new EventBusOptions().setClusterPublicHost("192.168.1.68").setClusterPublicPort(2));

		Vertx.clusteredVertx(options).onComplete(res -> {
			if (res.succeeded()) {
				Vertx vertx = res.result();
				EventBus eventBus = vertx.eventBus();
				eventBus.publish("synAppCode", "hello world");
			} else {
				System.out.println("Failed: " + res.cause());
			}
		});
	}

}
