import unittest
from modelverse_state.main import ModelverseState

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

    def test_read_reverse_dict_no_exists(self):
        l = self.mvs.read_reverse_dict(-1, "abc")
        assert l == None

    def test_read_reverse_dict_not_found_node(self):
        a = self.mvs.create_node()
        assert a != []

        # Passing data is not enforced, as the data will be interpreted if necessary
        l = self.mvs.read_reverse_dict(a, "abc")
        assert l == []

    def test_read_reverse_dict_not_found_nodevalue(self):
        a = self.mvs.create_nodevalue(1)
        assert a != None

        # Passing data is not enforced, as the data will be interpreted if necessary
        l = self.mvs.read_reverse_dict(a, "abc")
        assert l == []

    def test_read_reverse_dict_not_found_edge(self):
        a = self.mvs.create_node()
        b = self.mvs.create_node()
        c = self.mvs.create_edge(a, b)
        assert a != None
        assert b != None
        assert c != None

        # Passing data is not enforced, as the data will be interpreted if necessary
        l = self.mvs.read_reverse_dict(c, "abc")
        assert l == []

    def test_read_reverse_dict_no_primitive(self):
        a = self.mvs.create_node()
        assert a != None

        # Passing data is not enforced, as the data will be interpreted if necessary
        l = self.mvs.read_reverse_dict(a, a)
        assert l == []

    def test_read_reverse_dict_node_simple(self):
        a = self.mvs.create_node()
        b = self.mvs.create_node()
        c = self.mvs.create_nodevalue("f")
        d = self.mvs.create_edge(a, b)
        e = self.mvs.create_edge(d, c)
        assert a != None
        assert b != None
        assert c != None
        assert d != None
        assert e != None

        l = self.mvs.read_reverse_dict(b, "f")
        assert set(l) == set([a])

    def test_read_reverse_dict_no_match(self):
        a = self.mvs.create_node()
        b = self.mvs.create_node()
        c = self.mvs.create_nodevalue("g")
        d = self.mvs.create_edge(a, b)
        e = self.mvs.create_edge(d, c)
        assert a != None
        assert b != None
        assert c != None
        assert d != None
        assert e != None

        l = self.mvs.read_reverse_dict(b, "f")
        assert l == []

    def test_read_reverse_dict_node_multi(self):
        a = self.mvs.create_node()
        b = self.mvs.create_node()
        c = self.mvs.create_nodevalue("f")
        d = self.mvs.create_edge(a, b)
        e = self.mvs.create_edge(d, c)
        assert a != None
        assert b != None
        assert c != None
        assert d != None
        assert e != None

        g = self.mvs.create_node()
        h = self.mvs.create_nodevalue("k")
        i = self.mvs.create_edge(a, g)
        j = self.mvs.create_edge(i, h)
        assert g != None
        assert h != None
        assert i != None
        assert j != None

        l = self.mvs.read_reverse_dict(b, "f")
        assert set(l) == set([a])

        l = self.mvs.read_reverse_dict(g, "k")
        assert set(l) == set([a])

        l = self.mvs.read_reverse_dict(a, "l")
        assert l == []

    def test_read_reverse_dict_node_multi_ambiguous(self):
        a = self.mvs.create_node()
        b = self.mvs.create_node()
        c = self.mvs.create_nodevalue("f")
        d = self.mvs.create_edge(b, a)
        e = self.mvs.create_edge(d, c)
        assert a != None
        assert b != None
        assert c != None
        assert d != None
        assert e != None

        g = self.mvs.create_node()
        h = self.mvs.create_nodevalue("f")
        i = self.mvs.create_edge(g, a)
        j = self.mvs.create_edge(i, h)
        assert g != None
        assert h != None
        assert i != None
        assert j != None

        l = self.mvs.read_reverse_dict(a, "f")
        assert set(l) == set([b, g])

    def test_read_reverse_dict_node_uncertain(self):
        a = self.mvs.create_node()
        b = self.mvs.create_node()
        c = self.mvs.create_nodevalue("f")
        d = self.mvs.create_edge(a, b)
        e = self.mvs.create_edge(d, c)
        assert a != None
        assert b != None
        assert c != None
        assert d != None
        assert e != None

        h = self.mvs.create_nodevalue("g")
        i = self.mvs.create_edge(d, h)
        assert h != None
        assert i != None

        l = self.mvs.read_reverse_dict(b, "f")
        assert set(l) == set([a])
