import os
import warnings
from json import dumps, loads
from pytest import fixture  # , raises
from pathlib import Path
from contextlib import chdir
from rougail import Rougail
from rougail.output_doc import RougailOutputDoc as RougailOutput

from rougail_tests.utils import get_structures_list, get_rougail_config, get_values_for_config


HERE = Path(__file__).parent


excludes = []
excludes = [
    '60_5family_dynamic_unknown_suffix',
    '60_5family_dynamic_variable_outside_sub_suffix',
]

test_ok = get_structures_list(excludes)
# test_ok = [HERE.parent.parent / "rougail-tests" / "structures" / "40_0leadership_leader_follower"]

os.environ['COLUMNS'] = '80'


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_structural_files(test_dir, namespace, ext, *, examples=False):
    with chdir(HERE):
        rougailconfig = get_rougail_config(test_dir, namespace, relative_to=HERE)
        if not rougailconfig:
            return
        rougailconfig['tiramisu_cache'] = 'p.py'
        ##################################
        rougailconfig['step.output'] = 'doc'
        rougailconfig['doc.output_format'] = ext
        ext = {'github': 'md', 'asciidoc': 'adoc', 'json': 'json', 'console': 'sh', 'gitlab': 'gitlab.md'}.get(ext)
        if examples:
            rougailconfig['doc.example'] = True
        else:
            rougailconfig['doc.example'] = False
        ##################################
        dir_name = 'test'
        if namespace:
            dir_name += '_namespace'
        elif (test_dir / 'force_namespace').is_file():
            return
        ##################################
        if examples:
            dir_name += '_examples'
        ##################################
        rougail = Rougail(rougailconfig)
        warnings.simplefilter("always", UserWarning)
        with warnings.catch_warnings(record=True) as wn:
            config = rougail.run()
            generated_output = RougailOutput(config, rougailconfig=rougailconfig).run()[1]
        output_file = HERE / '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}'
        #
        warns = [str(w.message) for w in wn]
        output_file = HERE / 'results' / dir_name / ("warnings_" + test_dir.name)
        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(dumps(warns))
        with output_file.open() as outfh:
             attented_output = loads(outfh.read())
        assert warns == attented_output, f'filename {output_file}'


def test_structural_files_json(test_dir):
    _test_structural_files(test_dir, True, 'json')


def test_structural_files_console(test_dir):
    _test_structural_files(test_dir, True, 'console')


def test_structural_files_github(test_dir):
    _test_structural_files(test_dir, True, 'github')


def test_structural_files_gitlab(test_dir):
    _test_structural_files(test_dir, True, 'gitlab')


def test_structural_files_asciidoc(test_dir):
    _test_structural_files(test_dir, True, 'asciidoc')

################
def test_structural_files_examples(test_dir):
    _test_structural_files(test_dir, True, 'github', examples=True)

################
def test_structural_files_json_no_namespace(test_dir):
    _test_structural_files(test_dir, False, 'json')


def test_structural_files_console_no_namespace(test_dir):
    _test_structural_files(test_dir, False, 'console')


def test_structural_files_github_no_namespace(test_dir):
    _test_structural_files(test_dir, False, 'github')


def test_structural_files_gitlab_no_namespace(test_dir):
    _test_structural_files(test_dir, False, 'gitlab')


def test_structural_files_asciidoc_no_namespace(test_dir):
    _test_structural_files(test_dir, False, 'asciidoc')

################
def test_structural_files_examples_no_namespace(test_dir):
    _test_structural_files(test_dir, False, 'github', examples=True)
