from pathlib import Path
from json import dump, load
from rougail import Rougail, RougailConfig
from rougail.user_data_yaml import RougailUserDataYaml


def _test_invalid_no_error(filename):
    rougailconfig = RougailConfig.copy()
    rougailconfig["main_namespace"] = None
    rougailconfig["main_structural_directories"] = ["tests/invalid/structure"]
    rougailconfig['step.user_data'] = ['yaml']
    rougailconfig['yaml.filename'] = [f"tests/invalid/{filename}"]
    rougail = Rougail(rougailconfig)
    config = rougail.run()
    for invalid_user_data_error in [False, True]:
        if invalid_user_data_error:
            ifilename = f"{filename}_invalid"
        else:
            ifilename = filename
        for unknown_user_data_error in [False, True]:
            if unknown_user_data_error:
                ufilename = f"{ifilename}_unknown"
            else:
                ufilename = ifilename
            generated_user_data = RougailUserDataYaml(config, rougailconfig=rougailconfig).run()
            errors = rougail.user_data(generated_user_data, invalid_user_data_error=invalid_user_data_error, unknown_user_data_error=unknown_user_data_error)
            for l, data in errors.items():
                for i, d in enumerate(data):
                    if isinstance(d, dict):
                        data[i] = [[l, v.path, v.index] for l, v in d.items()]
            #expected output
            expected_filename = Path('tests') / 'invalid' / 'results' / ufilename / "errors.json"
            if not expected_filename.is_file():
                expected_filename.parent.mkdir(parents=True, exist_ok=True)
                with open(expected_filename, 'a') as json_file:
                    dump(errors, json_file, indent=4)
            with open(expected_filename) as json_file:
                expected_errors = load(json_file)
            assert expected_errors == errors, expected_filename


def test_invalid():
    _test_invalid_no_error("invalid")


def test_invalid_dyn():
    _test_invalid_no_error("invalid_dyn")


def test_invalid_family():
    _test_invalid_no_error("invalid_family")


def test_invalid_leadership():
    _test_invalid_no_error("invalid_leadership")


def test_invalid_multi():
    _test_invalid_no_error("invalid_multi")


def test_invalid_multi2():
    _test_invalid_no_error("invalid_multi2")


def test_invalid_unknown():
    _test_invalid_no_error("unknown")


def test_invalid_unknown2():
    _test_invalid_no_error("unknown2")
