from pytest import fixture  # , raises
from pathlib import Path
from rougail import Rougail
from rougail.output_console import RougailOutputConsole as RougailOutput

from rougail_tests.utils import get_structures_list, get_rougail_config, get_values_for_config


EXT = 'sh'


excludes = []
#excludes = [
#    '60_2family_dynamic_jinja_fill_sub_group',
#    '60_2family_dynamic_jinja_fill_sub_group_2',
#]

test_ok = get_structures_list(excludes)
# test_ok = [Path('../rougail-tests/structures/40_0leadership_follower_default_submulti')]


def idfn(fixture_value):
    return fixture_value.name


@fixture(scope="module", params=test_ok, ids=idfn)
def test_dir(request):
    return request.param


def _test_dictionaries(test_dir, namespace, ext, *, read_write=True, mandatory=False, show_secrets=False, do_calc=True):
    rougailconfig = get_rougail_config(test_dir, namespace)
    if not rougailconfig:
        return
    ##################################
    rougailconfig['step.output'] = 'console'
    rougailconfig["console.read_write"] = read_write
    rougailconfig["console.mandatory"] = mandatory
    rougailconfig["console.show_secrets"] = show_secrets
    ##################################
    dir_name = 'test'
    if namespace:
        dir_name += '_namespace'
    elif (test_dir / 'force_namespace').is_file():
        return
    ##################################
    if read_write:
        dir_name += '_read_write'
    if mandatory:
        dir_name += '_mandatory'
    if not show_secrets:
        dir_name += '_secrets'
    if not do_calc:
        dir_name += '_errors'
    ##################################
    rougail = Rougail(rougailconfig)
    config = rougail.run()
    ##################################
    if do_calc and (mandatory or not read_write):
        get_values_for_config(config)
    ##################################
    generated_output = RougailOutput(config, rougailconfig=rougailconfig).run()[1]
    output_file = Path(__file__).parent / 'results' / dir_name / (test_dir.name + "." + ext)
    if not output_file.is_file():
        if not output_file.parent.is_dir():
            output_file.parent.mkdir()
        with output_file.open('w') as outfh:
            outfh.write(generated_output)
    with output_file.open() as outfh:
         attented_output = outfh.read()
    assert generated_output == attented_output, f'filename {output_file}'


def test_dictionaries_console(test_dir):
    _test_dictionaries(test_dir, True, EXT)


def test_dictionaries_console_errors(test_dir):
    _test_dictionaries(test_dir, True, EXT, do_calc=False, mandatory=True)


def test_dictionaries_console_read_only(test_dir):
    _test_dictionaries(test_dir, True, EXT, read_write=False)


def test_dictionaries_console_mandatory(test_dir):
    _test_dictionaries(test_dir, True, EXT, mandatory=True)


def test_dictionaries_console_mandatory_read_only(test_dir):
    _test_dictionaries(test_dir, True, EXT, read_write=False, mandatory=True)


def test_dictionaries_console_secrets(test_dir):
    _test_dictionaries(test_dir, True, EXT, show_secrets=True)


#################
def test_dictionaries_console_namespace(test_dir):
    _test_dictionaries(test_dir, False, EXT)


def test_dictionaries_console_namespace_errors(test_dir):
    _test_dictionaries(test_dir, False, EXT, do_calc=False, mandatory=True)


def test_dictionaries_console_namespace_read_only(test_dir):
    _test_dictionaries(test_dir, False, EXT, read_write=False)


def test_dictionaries_console_namespace_mandatory(test_dir):
    _test_dictionaries(test_dir, False, EXT, mandatory=True)


def test_dictionaries_console_namespace_mandatory_read_only(test_dir):
    _test_dictionaries(test_dir, False, EXT, read_write=False, mandatory=True)


def test_dictionaries_console_namespace_secrets(test_dir):
    _test_dictionaries(test_dir, False, EXT, show_secrets=True)