import unittest
from modelverse_state.main import ModelverseState

from modelverse_state import status

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

    def test_create_nodevalue_different_id_simple(self):
        id1, r1 = self.mvs.create_nodevalue(1)
        id2, r2 = self.mvs.create_nodevalue(1)
        
        self.assertEquals(r1, status.SUCCESS)
        self.assertEquals(r2, status.SUCCESS)
        self.assertNotEquals(id1, id2)

    def test_create_nodevalue_read(self):
        id1, r1 = self.mvs.create_nodevalue(1)
        self.assertEquals(r1, status.SUCCESS)
        val, r2 = self.mvs.read_value(id1)
        self.assertEquals(r2, status.SUCCESS)
        self.assertEquals(val, 1)

    def test_create_nodevalue_integer_ib_zero(self):
        # Nicely within range
        v = set()
        size = 0
        for i in range(-10, 10):
            id1, r = self.mvs.create_nodevalue(i)
            self.assertEquals(r, status.SUCCESS)
            size += 1
            v.add(id1)
        self.assertEquals(len(v), size)

    def test_create_nodevalue_boolean(self):
        id1, r1 = self.mvs.create_nodevalue(True)
        id2, r2 = self.mvs.create_nodevalue(False)
        
        self.assertEquals(r1, status.SUCCESS)
        self.assertEquals(r2, status.SUCCESS)
        self.assertNotEquals(id1, id2)

    def test_create_nodevalue_boolean_same(self):
        id1, r1 = self.mvs.create_nodevalue(True)
        id2, r2 = self.mvs.create_nodevalue(True)
        
        self.assertEquals(r1, status.SUCCESS)
        self.assertEquals(r2, status.SUCCESS)
        self.assertNotEquals(id1, id2)

    def test_create_nodevalue_float_keeps_type(self):
        id1, r = self.mvs.create_nodevalue(0.0)
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(type(v), float)
        self.assertEquals(v, 0.0)

    def test_create_nodevalue_string_empty(self):
        id1, r = self.mvs.create_nodevalue("")
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(type(v), str)
        self.assertEquals(v, "")

    def test_create_nodevalue_string_normal(self):
        id1, r = self.mvs.create_nodevalue("ABC")
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(type(v), str)
        self.assertEquals(v, "ABC")

    def test_create_nodevalue_string_not_parsed(self):
        id1, r = self.mvs.create_nodevalue("1")
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(type(v), str)
        self.assertEquals(v, "1")

        id1, r = self.mvs.create_nodevalue("1.0")
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(type(v), str)
        self.assertEquals(v, "1.0")

        id1, r = self.mvs.create_nodevalue("-1.0")
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(type(v), str)
        self.assertEquals(v, "-1.0")

        id1, r = self.mvs.create_nodevalue("True")
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(type(v), str)
        self.assertEquals(v, "True")

    def test_create_nodevalue_junk(self):
        class Unknown(object):
            pass

        id1, r = self.mvs.create_nodevalue(Unknown())
        self.assertEquals(r, status.FAIL_CNV_OOB)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.FAIL_RV_UNKNOWN)
        self.assertEquals(v, None)

    def test_create_nodevalue_action_if(self):
        id1, r = self.mvs.create_nodevalue({"value": "if"})
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(v, {"value": "if"})

    def test_create_nodevalue_action_while(self):
        id1, r = self.mvs.create_nodevalue({"value": "while"})
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(v, {"value": "while"})

    def test_create_nodevalue_action_assign(self):
        id1, r = self.mvs.create_nodevalue({"value": "assign"})
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(v, {"value": "assign"})

    def test_create_nodevalue_action_call(self):
        id1, r = self.mvs.create_nodevalue({"value": "call"})
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(v, {"value": "call"})

    def test_create_nodevalue_action_break(self):
        id1, r = self.mvs.create_nodevalue({"value": "break"})
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(v, {"value": "break"})

    def test_create_nodevalue_action_continue(self):
        id1, r = self.mvs.create_nodevalue({"value": "continue"})
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(v, {"value": "continue"})

    def test_create_nodevalue_action_return(self):
        id1, r = self.mvs.create_nodevalue({"value": "return"})
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(v, {"value": "return"})

    def test_create_nodevalue_action_resolve(self):
        id1, r = self.mvs.create_nodevalue({"value": "resolve"})
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(v, {"value": "resolve"})

    def test_create_nodevalue_action_access(self):
        id1, r = self.mvs.create_nodevalue({"value": "access"})
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(v, {"value": "access"})

    def test_create_nodevalue_action_unknown(self):
        id1, r = self.mvs.create_nodevalue({"value": "unknown"})
        self.assertEquals(r, status.FAIL_CNV_OOB)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.FAIL_RV_UNKNOWN)

    def test_create_nodevalue_action_input(self):
        id1, r = self.mvs.create_nodevalue({"value": "input"})
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(v, {"value": "input"})

    def test_create_nodevalue_action_output(self):
        id1, r = self.mvs.create_nodevalue({"value": "output"})
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(v, {"value": "output"})

    def test_create_nodevalue_action_declare(self):
        id1, r = self.mvs.create_nodevalue({"value": "declare"})
        self.assertEquals(r, status.SUCCESS)
        v, r = self.mvs.read_value(id1)
        self.assertEquals(r, status.SUCCESS)
        self.assertEquals(v, {"value": "declare"})
