import unittest
from modelverse_state.main import ModelverseState

from modelverse_state import status

class TestCreateEdge(unittest.TestCase):
    def setUp(self):
        self.mvs = ModelverseState()

    def test_create_edge_invalid_source(self):
        a = -1
        b, r = self.mvs.create_node()
        self.assertEquals(r, status.SUCCESS)

        edge, r = self.mvs.create_edge(a, b)
        self.assertEquals(edge, None)
        self.assertEquals(r, status.FAIL_CE_SOURCE)

    def test_create_edge_invalid_target(self):
        b = -1
        a, r = self.mvs.create_node()
        self.assertEquals(r, status.SUCCESS)

        edge, r = self.mvs.create_edge(a, b)
        self.assertEquals(edge, None)
        self.assertEquals(r, status.FAIL_CE_TARGET)

    def test_create_edge_invalid_both(self):
        a = -1
        b = -1
        edge, r = self.mvs.create_edge(a, b)
        self.assertEquals(edge, None)
        self.assertEquals(r, status.FAIL_CE_SOURCE)

    def test_create_edge_node_to_node(self):
        a, r = self.mvs.create_node()
        self.assertEquals(r, status.SUCCESS)
        b, r = self.mvs.create_node()
        self.assertEquals(r, status.SUCCESS)

        edge, r = self.mvs.create_edge(a, b)
        self.assertGreater(edge,a)
        self.assertGreater(edge,b)
        self.assertEquals(r, status.SUCCESS)

    def test_create_edge_multiple(self):
        a, r = self.mvs.create_node()
        self.assertEquals(r, status.SUCCESS)
        b, r = self.mvs.create_node()
        self.assertEquals(r, status.SUCCESS)

        edge1, r = self.mvs.create_edge(a, b)
        self.assertGreater(edge1,a)
        self.assertGreater(edge1,b)
        self.assertEquals(r, status.SUCCESS)

        edge2, r = self.mvs.create_edge(a, b)
        self.assertGreater(edge2,a)
        self.assertGreater(edge2,b)
        self.assertEquals(r, status.SUCCESS)

        self.assertNotEquals(edge1, edge2)

    def test_create_edge_many(self):
        v = set()
        for i in range(1000):
            a, r = self.mvs.create_node()
            self.assertEquals(r, status.SUCCESS)
            b, r = self.mvs.create_node()
            self.assertEquals(r, status.SUCCESS)

            edge, r = self.mvs.create_edge(a, b)

            self.assertGreater(edge,a)
            self.assertGreater(edge,b)
            self.assertEquals(r, status.SUCCESS)
            v.add(edge)
        self.assertEquals(len(v), 1000)

    def test_create_edge_edge_to_node(self):
        a, r = self.mvs.create_node()
        self.assertEquals(r, status.SUCCESS)
        b, r = self.mvs.create_node()
        self.assertEquals(r, status.SUCCESS)

        edge1, r = self.mvs.create_edge(a, b)
        self.assertGreater(edge1,a)
        self.assertGreater(edge1,b)
        self.assertEquals(r, status.SUCCESS)

        edge2, r = self.mvs.create_edge(edge1, b)
        self.assertGreater(edge2,edge1)
        self.assertGreater(edge2,b)
        self.assertEquals(r, status.SUCCESS)

        self.assertNotEquals(edge1, edge2)

    def test_create_edge_node_to_edge(self):
        a, r = self.mvs.create_node()
        self.assertEquals(r, status.SUCCESS)
        b, r = self.mvs.create_node()
        self.assertEquals(r, status.SUCCESS)

        edge1, r = self.mvs.create_edge(a, b)
        self.assertGreater(edge1,a)
        self.assertGreater(edge1,b)
        self.assertEquals(r, status.SUCCESS)

        edge2, r = self.mvs.create_edge(a, edge1)
        self.assertGreater(edge2,a)
        self.assertGreater(edge2,edge1)
        self.assertEquals(r, status.SUCCESS)

        self.assertNotEquals(edge1, edge2)

    def test_create_edge_edge_to_edge(self):
        a, r = self.mvs.create_node()
        self.assertEquals(r, status.SUCCESS)
        b, r = self.mvs.create_node()
        self.assertEquals(r, status.SUCCESS)

        edge1, r = self.mvs.create_edge(a, b)
        self.assertGreater(edge1,a)
        self.assertGreater(edge1,b)
        self.assertEquals(r, status.SUCCESS)

        edge2, r = self.mvs.create_edge(a, b)
        self.assertGreater(edge2,a)
        self.assertGreater(edge2,b)
        self.assertEquals(r, status.SUCCESS)

        self.assertNotEquals(edge1, edge2)

        edge3, r = self.mvs.create_edge(edge1, edge2)
        self.assertGreater(edge3,edge1)
        self.assertGreater(edge3,edge2)
        self.assertEquals(r, status.SUCCESS)

    def test_create_edge_loop_node(self):
        a, r = self.mvs.create_node()
        self.assertEquals(r, status.SUCCESS)

        edge, r = self.mvs.create_edge(a, a)
        self.assertGreater(edge,a)
        self.assertEquals(r, status.SUCCESS)

    def test_create_edge_loop_edge(self):
        a, r = self.mvs.create_node()
        self.assertEquals(r, status.SUCCESS)

        edge1, r = self.mvs.create_edge(a, a)
        self.assertGreater(edge1,a)
        self.assertEquals(r, status.SUCCESS)

        edge2, r = self.mvs.create_edge(edge1, edge1)
        self.assertGreater(edge2,a)
        self.assertEquals(r, status.SUCCESS)
