/*
 * Copyright (c) 2008-2018, Hazelcast, Inc. All Rights Reserved.
 *
 * 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.hazelcast.cluster;

import com.hazelcast.config.Config;
import com.hazelcast.config.ListenerConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.LifecycleEvent;
import com.hazelcast.core.LifecycleListener;
import com.hazelcast.spi.properties.GroupProperty;
import com.hazelcast.test.HazelcastParallelClassRunner;
import com.hazelcast.test.annotation.ParallelTest;
import com.hazelcast.test.annotation.QuickTest;
import org.junit.After;
import org.junit.Test;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;

import java.util.concurrent.CountDownLatch;

import static com.hazelcast.test.HazelcastTestSupport.assertOpenEventually;

@RunWith(HazelcastParallelClassRunner.class)
@Category({QuickTest.class, ParallelTest.class})
public class NodeShutdownEventsTest {

    @After
    public void shutdown() {
        Hazelcast.shutdownAll();
    }

    /**
     * When a node fails due to a join time out, it will be shutdowned.
     * In that scenario we are expecting lifecycle events (SHUTTING_DOWN & SHUTDOWN)
     * to be fired locally.
     */
    @Test
    public void testNodeShutdown_firesLifecycleEvents_afterJoinFailure() throws Exception {
        // Only expecting SHUTTING_DOWN & SHUTDOWN events so latch count should be 2.
        final CountDownLatch shutdownEventCount = new CountDownLatch(2);

        final Config config1 = new Config();

        final Config config2 = new Config();
        // force join failure.
        config2.setProperty(GroupProperty.MAX_JOIN_SECONDS.getName(), "-100");
        // add lifecycle listener.
        final ListenerConfig listenerConfig = new ListenerConfig();
        listenerConfig.setImplementation(new LifecycleListener() {
            @Override
            public void stateChanged(LifecycleEvent event) {
                // Only expecting SHUTTING_DOWN & SHUTDOWN.
                if (LifecycleEvent.LifecycleState.SHUTTING_DOWN.equals(event.getState())
                        || LifecycleEvent.LifecycleState.SHUTDOWN.equals(event.getState())) {
                    shutdownEventCount.countDown();
                }
            }
        });
        config2.addListenerConfig(listenerConfig);

        final HazelcastInstance node1 = Hazelcast.newHazelcastInstance(config1);
        try {
            final HazelcastInstance node2 = Hazelcast.newHazelcastInstance(config2);
        } catch (IllegalStateException e) {
            // ignore IllegalStateException since we are only testing lifecyle events.
        }

        assertOpenEventually(shutdownEventCount);
    }


}

@@ -736,90 +736,8 @@
 ig;%0A
-import com.hazelcast.core.Hazelcast;%0Aimport com.hazelcast.core.HazelcastInstance;%0A
 impo
@@ -922,24 +922,128 @@
 lassRunner;%0A
+import com.hazelcast.test.HazelcastTestSupport;%0Aimport com.hazelcast.test.TestHazelcastInstanceFactory;%0A
 import com.h
@@ -1133,32 +1133,8 @@
 st;%0A
-import org.junit.After;%0A
 impo
@@ -1300,68 +1300,29 @@
 tic 
-com.hazelcast.test.HazelcastTestSupport.assertOpenEventually
+org.junit.Assert.fail
 ;%0A%0A@
@@ -1454,89 +1454,38 @@
 est 
-%7B%0A%0A    @After%0A    public void shutdown() %7B%0A        Hazelcast.shutdownAll();%0A    %7D
+extends HazelcastTestSupport %7B
 %0A%0A  
@@ -1521,28 +1521,17 @@
 s du
-e to a join time out
+ring join
 , it
@@ -1547,14 +1547,13 @@
 shut
+ 
 down
-ed
 .%0A  
@@ -1757,25 +1757,8 @@
 re()
- throws Exception
  %7B%0A 
@@ -1928,42 +1928,188 @@
     
-final Config config1 = new Config(
+// Having different partition counts is cause of the join failure.%0A        Config config1 = new Config()%0A                .setProperty(GroupProperty.PARTITION_COUNT.getName(), %22111%22
 );%0A%0A
@@ -2116,22 +2116,16 @@
         
-final 
 Config c
@@ -2137,33 +2137,32 @@
 2 = new Config()
-;
 %0A        // forc
@@ -2158,144 +2158,78 @@
     
-// force join failure.%0A        config2.setProperty(GroupProperty.MAX_JOIN_SECONDS.getName(), %22-100%22);%0A        // add lifecycle listener.
+        .setProperty(GroupProperty.PARTITION_COUNT.getName(), %22222%22);%0A
 %0A   
@@ -2834,38 +2834,36 @@
 nfig);%0A%0A        
-final 
+Test
 HazelcastInstanc
@@ -2867,26 +2867,75 @@
 ance
- node1 = Hazelcast
+Factory factory = createHazelcastInstanceFactory();%0A        factory
 .new
@@ -2962,16 +2962,17 @@
 nfig1);%0A
+%0A
         
@@ -2994,77 +2994,100 @@
    f
-inal HazelcastInstance node2 = Hazelcast.newHazelcastInstance(config2
+actory.newHazelcastInstance(config2);%0A            fail(%22Second node should fail during join%22
 );%0A 
@@ -3205,16 +3205,17 @@
 g lifecy
+c
 le event
@@ -3284,12 +3284,10 @@
 ;%0A    %7D%0A
-%0A%0A
 %7D%0A

Fix NodeShutdownEventsTest