/*
 *      Copyright (C) 2012-2014 DataStax Inc.
 *
 *   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.datastax.driver.core;

import org.testng.annotations.Test;
import static org.testng.Assert.assertEquals;

import static com.datastax.driver.core.TestUtils.*;

/**
 * Simple test of the Sessions methods against a one node cluster.
 */
public class StateListenerTest {

    @Test(groups = "short")
    public void listenerTest() throws Throwable {

        CCMBridge.CCMCluster c = CCMBridge.buildCluster(1, Cluster.builder());
        Cluster cluster = c.cluster;

        try {
            CountingListener listener = new CountingListener();
            cluster.register(listener);

            c.cassandraCluster.bootstrapNode(2);
            waitFor(CCMBridge.IP_PREFIX + '2', cluster);

            // We sleep slightly before checking the listener because the node is marked UP
            // just before the listeners are called, and since waitFor is based on isUP,
            // it can return *just* before the listener are called.
            Thread.sleep(500);
            assertEquals(listener.adds, 1);

            c.cassandraCluster.forceStop(1);
            waitForDown(CCMBridge.IP_PREFIX + '1', cluster);
            Thread.sleep(500);
            assertEquals(listener.downs, 1);

            c.cassandraCluster.start(1);
            waitFor(CCMBridge.IP_PREFIX + '1', cluster);
            Thread.sleep(500);
            assertEquals(listener.ups, 1);

            c.cassandraCluster.decommissionNode(2);
            waitForDecommission(CCMBridge.IP_PREFIX + '2', cluster);
            Thread.sleep(500);
            assertEquals(listener.removes, 1);
        } catch (Throwable e) {
            c.errorOut();
            throw e;
        } finally {
            c.discard();
        }
    }

    private static class CountingListener implements Host.StateListener {

        public int adds;
        public int removes;
        public int ups;
        public int downs;

        public void onAdd(Host host) {
            adds++;
        }

        public void onUp(Host host) {
            ups++;
        }

        public void onSuspected(Host host) {
        }

        public void onDown(Host host) {
            downs++;
        }

        public void onRemove(Host host) {
            removes++;
        }
    }
}

@@ -656,16 +656,55 @@
 .core;%0A%0A
+import com.google.common.collect.Sets;%0A
 import o
@@ -731,16 +731,40 @@
 s.Test;%0A
+%0Aimport java.util.Set;%0A%0A
 import s
@@ -1704,16 +1704,23 @@
 ner.adds
+.size()
 , 1);%0A%0A 
@@ -1894,16 +1894,23 @@
 er.downs
+.size()
 , 1);%0A%0A 
@@ -2074,16 +2074,23 @@
 ener.ups
+.size()
 , 1);%0A%0A 
@@ -2281,16 +2281,23 @@
 .removes
+.size()
 , 1);%0A  
@@ -2529,94 +2529,198 @@
 lic 
-int adds;%0A        public int removes;%0A        public int ups;%0A        public int downs
+Set%3CHost%3E adds = Sets.newHashSet();%0A        public Set%3CHost%3E removes = Sets.newHashSet();%0A        public Set%3CHost%3E ups = Sets.newHashSet();%0A        public Set%3CHost%3E downs = Sets.newHashSet()
 ;%0A%0A 
@@ -2760,36 +2760,24 @@
 t) %7B
-%0A            adds++;%0A       
+ adds.add(host);
  %7D%0A%0A
@@ -2817,35 +2817,23 @@
 t) %7B
-%0A            ups++;%0A       
+ ups.add(host);
  %7D%0A%0A
@@ -2876,25 +2876,16 @@
  host) %7B
-%0A        
 %7D%0A%0A     
@@ -2922,37 +2922,25 @@
 t) %7B
-%0A            downs++;%0A       
+ downs.add(host);
  %7D%0A%0A
@@ -2984,39 +2984,27 @@
 t) %7B
-%0A            removes++;%0A       
+ removes.add(host);
  %7D%0A 

Update StateListenerTest#listenerTest to handle duplicate events.