from django.core.exceptions import ValidationError

from ...utils import link_status_changed


class TestLinkMixin(object):
    def _get_nodes(self):
        return self.node_model.objects.all()

    def test_str(self):
        t = self.topology_model.objects.first()
        node1, node2 = self._get_nodes()
        link = t._create_link(source=node1, target=node2, cost=1.0)
        self.assertIsInstance(str(link), str)

    def test_clean_properties(self):
        t = self.topology_model.objects.first()
        node1, node2 = self._get_nodes()
        link = t._create_link(source=node1, target=node2, cost=1.0, properties=None)
        link.full_clean()
        self.assertEqual(link.properties, {})

    def test_same_source_and_target_id(self):
        t = self.topology_model.objects.first()
        node_id = self.node_model.objects.first().pk
        link = t._create_link(source_id=node_id, target_id=node_id, cost=1)
        with self.assertRaises(ValidationError):
            link.full_clean()

    def test_same_source_and_target(self):
        t = self.topology_model.objects.first()
        node = self.node_model.objects.first()
        link = t._create_link(source=node, target=node, cost=1)
        with self.assertRaises(ValidationError):
            link.full_clean()

    def test_json(self):
        t = self.topology_model.objects.first()
        node1, node2 = self._get_nodes()
        link = t._create_link(source=node1, target=node2, cost=1.0,
                              cost_text='100mbit/s',
                              properties={"pretty": True})
        self.assertEqual(dict(link.json(dict=True)), {
            'source': '192.168.0.1',
            'target': '192.168.0.2',
            'cost': 1.0,
            'cost_text': '100mbit/s',
            'properties': {
                'pretty': True,
                'status': 'up',
                'created': link.created,
                'modified': link.modified,
                'status_changed': link.status_changed,
            }
        })
        self.assertIsInstance(link.json(), str)

    def test_get_from_nodes(self):
        t = self.topology_model.objects.first()
        node1, node2 = self._get_nodes()
        link = t._create_link(source=node1, target=node2, cost=1.0,
                              cost_text='100mbit/s', properties='{"pretty": true}')
        link.full_clean()
        link.save()
        link = self.link_model.get_from_nodes('192.168.0.1', '192.168.0.2', t)
        self.assertIsInstance(link, self.link_model)
        link = self.link_model.get_from_nodes('wrong', 'wrong', t)
        self.assertIsNone(link)

    def test_status_change_signal_sent(self):
        self.signal_was_called = False
        t = self.topology_model.objects.first()
        node1, node2 = self._get_nodes()
        link = t._create_link(source=node1, target=node2, cost=1.0, status='up')
        link.save()

        def handler(sender, link, **kwargs):
            self.signal_was_called = True
            self.assertEqual(link.pk, link.pk)
            self.assertEqual(link.status, 'down')

        link_status_changed.connect(handler)
        link.status = 'down'
        link.save()

        self.assertTrue(self.signal_was_called)
        link_status_changed.disconnect(handler)
