import unittest

from nose.tools \
    import \
        assert_equal

from toydist.core.parser.parser \
    import \
        parse
from toydist.core.parser.nodes \
    import \
        ast_walk
from toydist.core.parser.visitor \
    import \
        Dispatcher

def parse_and_analyse(data):
    p = parse(data)
    dispatcher = Dispatcher()
    res = ast_walk(p, dispatcher)

    return res

def _empty_description():
    d = {"libraries": {}, "paths": {}, "flags": {}}
    return d

def _empty_library():
    d = {"name": "default", "modules": [], "packages": [], "extensions": {}}
    return d

class TestSimpleMeta(unittest.TestCase):
    def test_name(self):
        data = """\
Name: foo
"""
        ref = _empty_description()
        ref["name"] = "foo"

        assert_equal(parse_and_analyse(data), ref)

class TestDescription(unittest.TestCase):
    def test_simple_single_line(self):
        data = "Description: some simple description"

        ref = _empty_description()
        ref["description"] = " some simple description"
        assert_equal(parse_and_analyse(data), ref)

    def test_simple_indented_block(self):
        data = """\
Description:
    some simple description
    on multiple
    lines.
"""

        ref = _empty_description()
        ref["description"] = "some simple description\non multiple\nlines."
        assert_equal(parse_and_analyse(data), ref)

    def test_simple_indented_block2(self):
        data = """\
Description: some simple description
    on multiple
    lines.
"""

        ref = _empty_description()
        ref["description"] = " some simple description\non multiple\nlines."
        assert_equal(parse_and_analyse(data), ref)

    def test_nested_indented_block3(self):
        data = """\
Description: some
    simple
        description
            on
    
    multiple

    lines.
"""

        ref = _empty_description()
        ref["description"] = """ some
simple
    description
        on

multiple

lines.\
"""
        assert_equal(parse_and_analyse(data), ref)

class TestLibrary(unittest.TestCase):
    def test_modules(self):
        data = """\
Library:
    Modules: foo.py
"""

        descr = _empty_description()
        library = _empty_library()
        library["modules"] = ["foo.py"]
        descr["libraries"]["default"] = library

        assert_equal(parse_and_analyse(data), descr)

    def test_simple_extension(self):
        data = """\
Library:
    Extension: _foo
        Sources: foo.c
"""
        descr = _empty_description()
        library = _empty_library()
        library["extensions"]["_foo"] = {"name": "_foo", "sources": ["foo.c"]}
        descr["libraries"]["default"] = library

        assert_equal(parse_and_analyse(data), descr)

class TestPath(unittest.TestCase):
    def test_simple(self):
        data = """\
Path: manpath
    Description: man path
    Default: /usr/share/man
"""

        descr = _empty_description()
        descr["paths"]["manpath"] = {
                "name": "manpath",
                "default": "/usr/share/man",
                "description": " man path",
                }

        assert_equal(parse_and_analyse(data), descr)

class TestFlag(unittest.TestCase):
    def test_simple(self):
        data = """\
Flag: debug
    Description: debug flag
    Default: false
"""

        descr = _empty_description()
        descr["flags"]["debug"] = {
                "name": "debug",
                "default": "false",
                "description": " debug flag",
                }

        assert_equal(parse_and_analyse(data), descr)

class TestConditional(unittest.TestCase):
    def test_literal(self):
        data = """\
Library:
    if true:
        Modules: foo.py, bar.py
    else:
        Modules:  fubar.py
"""

        descr = _empty_description()
        descr["libraries"]["default"] = _empty_library()
        descr["libraries"]["default"]["modules"] = ["foo.py", "bar.py"]

        assert_equal(parse_and_analyse(data), descr)

        data = """\
Library:
    if false:
        Modules: foo.py, bar.py
    else:
        Modules:  fubar.py
"""
        descr["libraries"]["default"]["modules"] = ["fubar.py"]

        assert_equal(parse_and_analyse(data), descr)

@@ -8,16 +8,27 @@
 unittest
+%0Aimport sys
 %0A%0Afrom n
@@ -4191,28 +4191,405 @@
 e_and_analyse(data), descr)%0A
+%0A    def test_os(self):%0A        data = %22%22%22%5C%0ALibrary:%0A    if os(%25s):%0A        Modules: foo.py, bar.py%0A    else:%0A        Modules:  fubar.py%0A%22%22%22 %25 sys.platform%0A%0A        descr = _empty_description()%0A        descr%5B%22libraries%22%5D%5B%22default%22%5D = _empty_library()%0A        descr%5B%22libraries%22%5D%5B%22default%22%5D%5B%22modules%22%5D = %5B%22foo.py%22, %22bar.py%22%5D%0A%0A        assert_equal(parse_and_analyse(data), descr)%0A

add test for os() conditional handling in visitor.