import logging

import pytest

from dtest import Tester
from tools.misc import new_node

since = pytest.mark.since
logger = logging.getLogger(__name__)

class TestGossip(Tester):
    """
    This test suite looks at how gossip information is distributed within
    a cluster under various scenarios that alter gossip state.
    """
    @pytest.mark.no_vnodes
    def test_assassination_of_unknown_node(self):
        """
        @jira_ticket CASSANDRA-16588
        Test that a non-seed node can come back online after assassinating an
        unknown node.
        """
        cluster = self.cluster

        # Create a 5-node cluster
        cluster.populate(5)
        node1 = cluster.nodelist()[0]
        node3 = cluster.nodelist()[2]

        self.cluster.set_configuration_options({
            'seed_provider': [{'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider',
                               'parameters': [{'seeds': node1.address()}]
                              }]
            })

        cluster.start()

        logger.debug("Shutting down node {}".format(node3.address()))
        node3.stop()

        logger.debug("Assassinating unknown node 11.1.1.1")
        out, err, _ = node1.nodetool("assassinate 11.1.1.1")
        assert len(err.strip()) <= 0, "nodetool command failed: {}".format(err)

        logger.debug("Starting node {}".format(node3.address()))
        node3.start()

    def test_assassinate_valid_node(self):
        """
        @jira_ticket CASSANDRA-16588
        Test that after taking two non-seed nodes down and assassinating
        one of them, the other can come back up.
        """
        cluster = self.cluster

        cluster.populate(5).start()
        node1 = cluster.nodelist()[0]
        node3 = cluster.nodelist()[2]

        self.cluster.set_configuration_options({
            'seed_provider': [{'class_name': 'org.apache.cassandra.locator.SimpleSeedProvider',
                               'parameters': [{'seeds': node1.address()}]
                              }]
            })

        non_seed_nodes = cluster.nodelist()[-2:]
        for node in non_seed_nodes:
            node.stop()

        assassination_target = non_seed_nodes[0]
        logger.debug("Assassinating non-seed node {}".format(assassination_target.address()))
        out, err, _ = node1.nodetool("assassinate {}".format(assassination_target.address()))
        assert len(err.strip()) <= 0, "nodetool command failed: {}".format(err)

        logger.debug("Starting non-seed nodes")
        for node in non_seed_nodes:
            node.start()

    def _cluster_create_node(self, num):
        address = '127.0.0.%d' % num
        return self.cluster.create_node("node%s" % num, False, None,
                                        (address, 7000 + num),
                                        str(7100 + num), str(2000 + num), None,
                                        binary_interface=(address, 9042))

    def _start_nodes_in_parallel(self, nodelist):
        for node in nodelist:
            node.start(no_wait=True)

        # Wait 30 seconds for nodes to come up
        for _ in range(30):
            if [n for n in nodelist if n.is_running()] == nodelist:
                break
            time.sleep(1)

        for node in nodelist:
            assert node.is_running()

    def _create_2dc_cluster(self):
        cluster = self.cluster
        cluster.set_configuration_options(values={'endpoint_snitch': 'org.apache.cassandra.locator.PropertyFileSnitch'})

        # Add dc1 nodes
        node1 = self._cluster_create_node(1)
        cluster.add(node1, True, data_center='dc1')
        node1.start()
        node2 = self._cluster_create_node(2)
        cluster.add(node2, False, data_center='dc1')
        node2.start()

        # Add dc2 nodes
        node3 = self._cluster_create_node(3)
        cluster.add(node3, True, data_center='dc2')
        node3.start()
        node4 = self._cluster_create_node(4)
        cluster.add(node4, False, data_center='dc2')
        node4.start()

        # Stop cluster
        for node in cluster.nodelist():
            node.stop()

        return node1, node2, node3, node4

    @since('4.0')
    def test_2dc_parallel_startup(self):
        """
        @jira_ticket CASSANDRA-16588
        Given a 2 DC cluster, start all seeds node in parallel followed by
        all non-seed nodes in parallel.
        """
        node1, node2, node3, node4 = self._create_2dc_cluster()

        # Start seeds in parallel
        self._start_nodes_in_parallel([node1, node3])

        # Start non-seeds in parallel
        self._start_nodes_in_parallel([node2, node4])

    @since('4.0')
    def test_2dc_parallel_startup_one_seed(self):
        """
        @jira_ticket CASSANDRA-16588
        Given a 2 DC cluster, start one seed node followed by all non-seed
        nodes in parallel.
        """
        node1, node2, node3, node4 = self._create_2dc_cluster()

        # Start one seed (of two)
        self._start_nodes_in_parallel([node1])

        # Start non-seeds in parallel
        self._start_nodes_in_parallel([node2, node4])
