from lxml import etree
from os.path import isfile, join, isdir
from pytest import fixture, raises
from os import listdir
from json import load

from rougail import objspace, annotator
from rougail.xml_compare import xml_compare
from rougail.error import CreoleDictConsistencyError
from rougail.config import dtdfilename



destfile = '/tmp/test.xml'
dico_dirs = 'tests/flattener_dicos'


test_ok = set()
test_raise = set()

for test in listdir(dico_dirs):
    if isdir(join(dico_dirs, test)):
        if isdir(join(dico_dirs, test, 'result')):
            test_ok.add(test)
        else:
            test_raise.add(test)

excludes = set([])
test_ok -= excludes
test_raise -= excludes
#test_ok = ['10autosave_hidden']
#test_raise = []


test_ok = list(test_ok)
test_raise = list(test_raise)
test_ok.sort()
test_raise.sort()


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


@fixture(scope="module", params=test_raise)
def test_dir_error(request):
    return request.param


def compare_xml(exported_xmlfile, expected_xmlfile):
    exported_document = etree.parse(exported_xmlfile).getroot()
    expected_document = etree.parse(expected_xmlfile).getroot()
    try:
        assert xml_compare(exported_document, expected_document)
    except AssertionError as err:
        print()
        print('Le dictionnaire exporte :')
        print()
        print(etree.tostring(exported_document, pretty_print=True, encoding="UTF-8").decode())
        print()
        print('Le dictionnaire attendu :')
        print()
        print(etree.tostring(expected_document, pretty_print=True, encoding="UTF-8").decode())
        raise err


def launch_flattener(test_dir):
    eolobj = objspace.CreoleObjSpace(dtdfilename)
    dirs = [test_dir]
    subfolder = join(test_dir, 'subfolder')
    if isdir(subfolder):
        dirs.append(subfolder)
    eolobj.create_or_populate_from_xml('creole', dirs)
    subfolder = join(test_dir, 'extra_dirs', 'extra')
    if isdir(subfolder):
        eolobj.create_or_populate_from_xml('extra', [subfolder])
    subfolder = join(test_dir, 'extra_dirs', 'extra1')
    if isdir(subfolder):
        eolobj.create_or_populate_from_xml('extra1', [subfolder])
    eosfunc = join(dico_dirs, '../eosfunc/test.py')
    eolobj.space_visitor(eosfunc)
    eolobj.save(destfile)
    result_file = join(test_dir, 'result/00-base.xml')
    if isfile(result_file):
        # eolobj.save(result_file)
        compare_xml(destfile, result_file)


def fake_traduc(txt):
    return txt


def setup_module(module):
    module.traduc_ori = objspace._
    objspace._ = fake_traduc
    annotator._ = fake_traduc
    objspace.ServiceAnnotator = getattr(annotator, 'ServiceAnnotator')


def teardown_module(module):
    objspace._ = module.traduc_ori
    annotator._ = module.traduc_ori


def test_dictionary(test_dir):
    test_dir = join(dico_dirs, test_dir)
    launch_flattener(test_dir)


def test_error_dictionary(test_dir_error):
    test_dir = join(dico_dirs, test_dir_error)
    with raises(CreoleDictConsistencyError):
        launch_flattener(test_dir)


def test_no_dtd():
    with raises(IOError):
        eolobj = objspace.CreoleObjSpace('notexists.dtd')