import argparse
import sys
import traceback
import types

from mozlog import commandline, get_default_logger

class TestAssertion(Exception):
    pass

def assert_equals(a, b):
    if a != b:
        raise TestAssertion("%r not equal to %r" % (a, b))

def expected(status):
    def inner(f):
        def test_func():
            f()
        test_func.__name__ = f.__name__
        test_func._expected = status
        return test_func
    return inner

def test_that_passes():
    assert_equals(1, int("1"))

def test_that_fails():
    assert_equals(1, int("2"))

def test_that_has_an_error():
    assert_equals(2, 1 + "1")

@expected("FAIL")
def test_expected_fail():
    assert_equals(2 + 2, 5)

class TestRunner(object):
    def __init__(self):
        self.logger = get_default_logger(component='TestRunner')

    def gather_tests(self):
        for item in globals().itervalues():
            if type(item) == types.FunctionType and item.__name__.startswith("test_"):
                yield item.__name__, item

    def run(self):
        tests = list(self.gather_tests())

        self.logger.suite_start(tests=[name for name, func in tests])
        self.logger.info("Running tests")
        for name, func in tests:
            self.run_test(name, func)
        self.logger.suite_end()

    def run_test(self, name, func):
        self.logger.test_start(name)
        status = None
        message = None
        expected = func._expected if hasattr(func, "_expected") else "PASS"
        try:
            func()
        except TestAssertion as e:
            status = "FAIL"
            message = e.message
        except:
            status = "ERROR"
            message = traceback.format_exc()
        else:
            status = "PASS"
        self.logger.test_end(name, status=status, expected=expected, message=message)

def get_parser():
    parser = argparse.ArgumentParser()
    return parser

def main():
    parser = get_parser()
    commandline.add_logging_group(parser)

    args = parser.parse_args()

    logger = commandline.setup_logging("structured-example", args, {"raw": sys.stdout})

    runner = TestRunner()
    try:
        runner.run()
    except:
        logger.critical("Error during test run:\n%s" % traceback.format_exc())

if __name__ == "__main__":
    main()
