/*
 * Copyright 2013 gitblit.com.
 *
 * 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.gitblit.tests;

import static org.junit.Assert.assertEquals;

import java.text.MessageFormat;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

import org.junit.Test;

import com.gitblit.fanout.FanoutClient;
import com.gitblit.fanout.FanoutClient.FanoutAdapter;
import com.gitblit.fanout.FanoutNioService;
import com.gitblit.fanout.FanoutService;
import com.gitblit.fanout.FanoutSocketService;

public class FanoutServiceTest {
	
	int fanoutPort = FanoutService.DEFAULT_PORT;
	
	@Test
	public void testNioPubSub() throws Exception {
		testPubSub(new FanoutNioService(fanoutPort));
	}

	@Test
	public void testSocketPubSub() throws Exception {
		testPubSub(new FanoutSocketService(fanoutPort));
	}
	
	@Test
	public void testNioDisruptionAndRecovery() throws Exception {
		testDisruption(new FanoutNioService(fanoutPort));
	}

	@Test
	public void testSocketDisruptionAndRecovery() throws Exception {
		testDisruption(new FanoutSocketService(fanoutPort));
	}
	
	protected void testPubSub(FanoutService service) throws Exception {
		System.out.println(MessageFormat.format("\n\n========================================\nPUBSUB TEST {0}\n========================================\n\n", service.toString()));
		service.startSynchronously();
		
		final Map<String, String> announcementsA = new ConcurrentHashMap<String, String>();
		FanoutClient clientA = new FanoutClient("localhost", fanoutPort);
		clientA.addListener(new FanoutAdapter() {
			
			@Override
			public void announcement(String channel, String message) {
				announcementsA.put(channel, message);
			}
		});
		
		clientA.startSynchronously();

		final Map<String, String> announcementsB = new ConcurrentHashMap<String, String>();
		FanoutClient clientB = new FanoutClient("localhost", fanoutPort);
		clientB.addListener(new FanoutAdapter() {
			@Override
			public void announcement(String channel, String message) {
				announcementsB.put(channel, message);
			}
		});
		clientB.startSynchronously();

		
		// subscribe clients A and B to the channels
		clientA.subscribe("a");
		clientA.subscribe("b");
		clientA.subscribe("c");
		
		clientB.subscribe("a");
		clientB.subscribe("b");
		clientB.subscribe("c");
		
		// give async messages a chance to be delivered
		Thread.sleep(1000);
		
		clientA.announce("a", "apple");
		clientA.announce("b", "banana");
		clientA.announce("c", "cantelope");
		
		clientB.announce("a", "avocado");
		clientB.announce("b", "beet");
		clientB.announce("c", "carrot");

		// give async messages a chance to be delivered
		Thread.sleep(2000);

		// confirm that client B received client A's announcements
		assertEquals("apple", announcementsB.get("a"));
		assertEquals("banana", announcementsB.get("b"));
		assertEquals("cantelope", announcementsB.get("c"));

		// confirm that client A received client B's announcements
		assertEquals("avocado", announcementsA.get("a"));
		assertEquals("beet", announcementsA.get("b"));
		assertEquals("carrot", announcementsA.get("c"));
		
		clientA.stop();
		clientB.stop();
		service.stop();		
	}
	
	protected void testDisruption(FanoutService service) throws Exception  {
		System.out.println(MessageFormat.format("\n\n========================================\nDISRUPTION TEST {0}\n========================================\n\n", service.toString()));
		service.startSynchronously();
		
		final AtomicInteger pongCount = new AtomicInteger(0);
		FanoutClient client = new FanoutClient("localhost", fanoutPort);
		client.addListener(new FanoutAdapter() {
			@Override
			public void pong(Date timestamp) {
				pongCount.incrementAndGet();
			}
		});
		client.startSynchronously();
		
		// ping and wait for pong
		client.ping();	
		Thread.sleep(500);
		
		// restart client
		client.stop();
		Thread.sleep(1000);
		client.startSynchronously();		
		
		// ping and wait for pong
		client.ping();	
		Thread.sleep(500);
				
		assertEquals(2, pongCount.get());
		
		// now disrupt service
		service.stop();		
		Thread.sleep(2000);
		service.startSynchronously();
		
		// wait for reconnect
		Thread.sleep(2000);

		// ping and wait for pong
		client.ping();
		Thread.sleep(500);

		// kill all
		client.stop();
		service.stop();
		
		// confirm expected pong count
		assertEquals(3, pongCount.get());
	}
}