package com.atlassian.stash.internal.cluster;

import com.atlassian.bitbucket.cluster.ClusterNode;
import com.google.common.collect.ImmutableSet;
import com.hazelcast.core.Cluster;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.LifecycleService;
import com.hazelcast.core.Member;
import org.hamcrest.Matchers;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.Set;

import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasProperty;
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

@RunWith(MockitoJUnitRunner.class)
public class HazelcastClusterInformationTest {

    @Mock
    private Cluster cluster;
    @Mock
    private HazelcastInstance hazelcast;
    private HazelcastClusterInformation information;
    @Mock
    private Member local;
    @Mock
    private Member remote;

    @Before
    public void setup() {
        when(cluster.getLocalMember()).thenReturn(local);
        when(cluster.getMembers()).thenReturn(ImmutableSet.of(local, remote));

        when(hazelcast.getCluster()).thenReturn(cluster);

        when(local.getUuid()).thenReturn("local");

        when(remote.getUuid()).thenReturn("remote");

        information = new HazelcastClusterInformation(hazelcast);
    }

    @Test
    public void testGetLocalNode() {
        ClusterNode node = information.getLocalNode();
        assertNotNull(node);
        assertEquals("local", node.getId());

        verify(cluster).getLocalMember();
    }

    @Test
    public void testGetNodes() {
        Set<ClusterNode> nodes = information.getNodes();
        assertNotNull(nodes);
        assertEquals(2, nodes.size());
        //"local" < "remote"
        assertThat(nodes, Matchers.contains(
                hasProperty("id", equalTo("local")),
                hasProperty("id", equalTo("remote"))));
    }

    @Test
    public void testIsRunning() {
        LifecycleService lifecycleService = mock(LifecycleService.class);
        when(lifecycleService.isRunning()).thenReturn(true);

        when(hazelcast.getLifecycleService()).thenReturn(lifecycleService);

        assertTrue(information.isRunning());

        verify(hazelcast).getLifecycleService();
        verify(lifecycleService).isRunning();
    }
}
