from dbus_next import SignatureTree


def assert_simple_type(signature, type_):
    assert type_.token == signature
    assert type_.signature == signature
    assert len(type_.children) == 0


def test_simple():
    tree = SignatureTree('s')
    assert len(tree.types) == 1
    assert_simple_type('s', tree.types[0])


def test_multiple_simple():
    tree = SignatureTree('sss')
    assert len(tree.types) == 3
    for i in range(0, 3):
        assert_simple_type('s', tree.types[i])


def test_array():
    tree = SignatureTree('as')
    assert len(tree.types) == 1
    child = tree.types[0]
    assert child.signature == 'as'
    assert child.token == 'a'
    assert len(child.children) == 1
    assert_simple_type('s', child.children[0])


def test_array_multiple():
    tree = SignatureTree('asasass')
    assert len(tree.types) == 4
    assert_simple_type('s', tree.types[3])
    for i in range(0, 3):
        array_child = tree.types[i]
        assert array_child.token == 'a'
        assert array_child.signature == 'as'
        assert len(array_child.children) == 1
        assert_simple_type('s', array_child.children[0])


def test_array_nested():
    tree = SignatureTree('aas')
    assert len(tree.types) == 1
    child = tree.types[0]
    assert child.token == 'a'
    assert child.signature == 'aas'
    assert len(child.children) == 1
    nested_child = child.children[0]
    assert nested_child.token == 'a'
    assert nested_child.signature == 'as'
    assert len(nested_child.children) == 1
    assert_simple_type('s', nested_child.children[0])


def test_simple_struct():
    tree = SignatureTree('(sss)')
    assert len(tree.types) == 1
    child = tree.types[0]
    assert child.signature == '(sss)'
    assert len(child.children) == 3
    for i in range(0, 3):
        assert_simple_type('s', child.children[i])


def test_nested_struct():
    tree = SignatureTree('(s(s(s)))')
    assert len(tree.types) == 1
    child = tree.types[0]
    assert child.signature == '(s(s(s)))'
    assert child.token == '('
    assert len(child.children) == 2
    assert_simple_type('s', child.children[0])
    first_nested = child.children[1]
    assert first_nested.token == '('
    assert first_nested.signature == '(s(s))'
    assert len(first_nested.children) == 2
    assert_simple_type('s', first_nested.children[0])
    second_nested = first_nested.children[1]
    assert second_nested.token == '('
    assert second_nested.signature == '(s)'
    assert len(second_nested.children) == 1
    assert_simple_type('s', second_nested.children[0])


def test_struct_multiple():
    tree = SignatureTree('(s)(s)(s)')
    assert len(tree.types) == 3
    for i in range(0, 3):
        child = tree.types[0]
        assert child.token == '('
        assert child.signature == '(s)'
        assert len(child.children) == 1
        assert_simple_type('s', child.children[0])


def test_array_of_structs():
    tree = SignatureTree('a(ss)')
    assert len(tree.types) == 1
    child = tree.types[0]
    assert child.token == 'a'
    assert child.signature == 'a(ss)'
    assert len(child.children) == 1
    struct_child = child.children[0]
    assert struct_child.token == '('
    assert struct_child.signature == '(ss)'
    assert len(struct_child.children) == 2
    for i in range(0, 2):
        assert_simple_type('s', struct_child.children[i])


def test_dict_simple():
    tree = SignatureTree('a{ss}')
    assert len(tree.types) == 1
    child = tree.types[0]
    assert child.signature == 'a{ss}'
    assert child.token == 'a'
    assert len(child.children) == 1
    dict_child = child.children[0]
    assert dict_child.token == '{'
    assert dict_child.signature == '{ss}'
    assert len(dict_child.children) == 2
    assert_simple_type('s', dict_child.children[0])
    assert_simple_type('s', dict_child.children[1])


def test_dict_of_structs():
    tree = SignatureTree('a{s(ss)}')
    assert len(tree.types) == 1
    child = tree.types[0]
    assert child.token == 'a'
    assert child.signature == 'a{s(ss)}'
    assert len(child.children) == 1
    dict_child = child.children[0]
    assert dict_child.token == '{'
    assert dict_child.signature == '{s(ss)}'
    assert len(dict_child.children) == 2
    assert_simple_type('s', dict_child.children[0])
    struct_child = dict_child.children[1]
    assert struct_child.token == '('
    assert struct_child.signature == '(ss)'
    assert len(struct_child.children) == 2
    for i in range(0, 2):
        assert_simple_type('s', struct_child.children[i])
