from pathlib import Path
from rougail import Rougail, RougailConfig
from rougail.user_data_yaml import RougailUserDataYaml
from rougail.user_data import mandatories
from json import load, dump, loads, dumps
import shutil

from rougail_tests.utils import config_to_dict


TUTORIAL_ROUGAIL = "../rougail-tutorials_builder/examples/"
TMP = Path("tutorial_tmp")
RESULT = Path("tests") / "result_tutorial"

def test_tutorial():
    tmp_structural_files = TMP / "structural"
    tmp_types_files = TMP / "types"
    if TMP.is_dir():
        shutil.rmtree(TMP)
    tmp_structural_files.mkdir(parents=True)
    tmp_types_files.mkdir()
    namespace_support = False
    tmp_structural_files.mkdir(exist_ok=True)
    for src_exercice in sorted(Path(TUTORIAL_ROUGAIL).iterdir()):
        result_files = RESULT / src_exercice.name
        result_files.mkdir(parents=True, exist_ok=True)
        if (src_exercice / "namespace").is_file():
            namespace_support = True
        src_types = src_exercice / "types"
        if src_types.is_dir():
            for types in src_types.iterdir():
                for t in types.iterdir():
                    shutil.copy(t, tmp_types_files / t.name)
        for src_namespace in (src_exercice / "structural_files").iterdir():
            if not src_namespace.is_dir():
                continue
            structure_directory = tmp_structural_files / src_namespace.name
            structure_directory.mkdir(exist_ok=True)
            for filename in src_namespace.iterdir():
                if not filename.name.endswith('.yml'):
                    continue
                shutil.copyfile(filename, structure_directory / filename.name)
        src_configs = src_exercice / "config"
        if not src_configs.is_dir():
            continue
        rougailconfig = RougailConfig.copy()
        if namespace_support:
            rougailconfig['main_namespace'] = 'firefox'
            rougailconfig['main_structural_directories'] = [str(tmp_structural_files / "firefox")]
            if (tmp_structural_files / 'foxyproxy').is_dir():
                rougailconfig['extra_namespaces'] = {"foxyproxy": [str(tmp_structural_files / "foxyproxy")]}  # extra_namespaces
        else:
            rougailconfig['main_namespace'] = None
            rougailconfig['main_structural_directories'] = [str(structure_directory)]
        types = [str(t) for t in tmp_types_files.iterdir()]
        if types:
            rougailconfig['types'] = types
        tiramisu_tmp = TMP / "tiramisu.py"
        try:
            rougailconfig['tiramisu_cache'] = str(tiramisu_tmp)
        except:
            rougailconfig['cli.tiramisu_cache'] = str(tiramisu_tmp)
        rougailconfig['step.user_data'] = ['yaml']
        for src_config in src_configs.iterdir():
            if src_config.is_file():
                continue
            result_errors = result_files / f"errors_{src_config.name}.json"
            rougailconfig['yaml.filename'] = [str(f) for f in src_config.iterdir() if str(f).endswith('.yml')]
            #
            rougail = Rougail(rougailconfig)
            config = rougail.run()
            generated_user_data = RougailUserDataYaml(config, rougailconfig=rougailconfig).run()
            errors = rougail.user_data(generated_user_data)
            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()]
            if not result_errors.is_file():
                with result_errors.open('a') as json_file:
                    dump(errors, json_file, indent=4)
            with result_errors.open() as json_file:
                expected_errors = load(json_file)
            assert expected_errors == errors, result_errors
            #
            for read_write in [True, False]:
                if read_write:
                    config.property.read_write()
                    result_file = result_files / f"{src_config.name}_rw.json"
                else:
                    config.property.read_only()
                    result_file = result_files / f"{src_config.name}_ro.json"
                config_dict = []
                mandatories(config, config_dict)
                if config_dict:
                    for i, d in enumerate(config_dict):
                        if isinstance(d, dict):
                            config_dict[i] = [[l, v.path, v.index] for l, v in d.items()]
                else:
                    config_dict = dict(config_to_dict(config.value.get()))
#                    if src_exercice.name in ['181', '182'] and src_config.name in ['02', '03']:
#                        config_dict['foxyproxy.proxies.title'][0]['foxyproxy.proxies.color'] = '#9b3677'
                    if src_exercice.name in ['201', '202', '210', '240', '241'] and src_config.name in ['02', '03']:
                        config_dict['foxyproxy.proxies.title'][0]['foxyproxy.proxies.color'] = '#9b3677'
                    if src_exercice.name in ['210', '241'] and src_config.name in ['03']:
                        config_dict['foxyproxy.proxies.title'][1]['foxyproxy.proxies.color'] = '#9b3678'
                    if src_exercice.name in ['240', '241'] and src_config.name in ['02']:
                        config_dict['foxyproxy.proxies.title'][1]['foxyproxy.proxies.color'] = '#9b3678'
                    if src_exercice.name in ['210'] and src_config.name in ['03']:
                        config_dict['foxyproxy.proxies.title'][2]['foxyproxy.proxies.color'] = '#9b3679'
                if not result_file.is_file():
                    with result_file.open('a') as json_file:
                        dump(config_dict, json_file, indent=4)
                with result_file.open() as json_file:
                    expected = load(json_file)
                assert expected == config_dict, result_file
    shutil.rmtree(TMP)
