from tiramisu import StrOption, BoolOption, IntOption, ChoiceOption, OptionDescription, SymLinkOption
from py.test import raises, fixture
from io import StringIO
import sys
from os import listdir
from os.path import join, isdir
from contextlib import redirect_stdout, redirect_stderr
from argparse import ArgumentParser

#from pouet import TiramisuCmdlineParser
from tiramisu_cmdline_parser import TiramisuCmdlineParser


DATA_DIR = 'test/data/compare'
TEST_DIRS = []


for test in listdir(DATA_DIR):
    test_file = join(DATA_DIR, test)
    if isdir(test_file):
        TEST_DIRS.append(test_file)

TEST_DIRS.sort()
# TEST_DIRS.remove('test/data/compare/10_positional_list')
# TEST_DIRS = ['test/data/compare/10_positional_list']


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


def import_subfile_and_test(filename, parser, arg):
    parser_dict = []
    parser_system_err = []
    f = StringIO()
    with redirect_stderr(f):
        exec(open(filename).read())
        # print('arg', arg)
        try:
            parser_dict.append(parser.parse_args(arg).__dict__)
        except SystemExit as err:
            parser_system_err.append(str(err))
        else:
            parser_system_err.append(None)
    parser_error = f.getvalue()
    f = StringIO()
    with redirect_stdout(f):
        parser.print_help()
    parser_help = f.getvalue()
    return parser_dict, parser_system_err, parser_error, parser_help


def test_files(test_list):
    args = [[],
            # 10_positional
            ['bar'], ['foo', 'bar'],
            # 10_positional_int
            ['4'],
            # 20_bool
            ['--verbosity'], ['--verbosity', 'arg'],
            # 20_string
            ['--foo'], ['--foo', '--bar'], ['--foo', 'a'],
            ['--foo', 'a', '--foo', 'b'],
            # 20_int
            ['--int', '3'], ['--int', 'a'],
            # 20 choice
            ['--door', 'a'], ['--door', '1'],
            # 30_string_short
            ['-f', 'b'], ['--foo', 'c', '-f', 'b'],
            # 40 multi_bool
            ['-v'], ['-v', '-s'], ['-vs'],
            # 40_short_long
            ['-v', '--foo', '1'], ['-vf', '2'], ['-vf'], ['-vf', '-v'],
            # 40_positional_optional
            ['bar', '--verbosity'], ['--verbosity', 'bar'],
            ]
    for arg in args:
        # FIXME unknown argument is check before mandatory
        if test_list == 'test/data/compare/10_positional_list':
            check = False
            for subarg in arg:
                if not subarg.startswith('-'):
                    check = True
                    break
            if not check:
                continue
        tiramparser = TiramisuCmdlineParser('prog.py')
        tiramparser_dict, tiramparser_system_err, tiramparser_error, tiramparser_help = import_subfile_and_test(test_list + '/tiramisu.py',
                                                                                                                tiramparser, arg)
        #
        argparser = ArgumentParser('prog.py')
        argparser_dict, argparser_system_err, argparser_error, argparser_help = import_subfile_and_test(test_list + '/argparse.py',
                                                                                                        argparser, arg)
        # print('===>', test_list, arg)
        # print(tiramparser_dict)
        # print(tiramparser_system_err)
        # print(tiramparser_error)
        # print(tiramparser_help)
        # print('-----')
        # print(argparser_dict)
        # print(argparser_system_err)
        # print(argparser_error)
        # print(argparser_help)
        assert tiramparser_dict == argparser_dict
        assert tiramparser_error == argparser_error
        assert tiramparser_help == argparser_help
        assert tiramparser_system_err == argparser_system_err


#FIXME --verbose sans --quiet
#parser = argparse.ArgumentParser(description="calculate X to the power of Y")
#group = parser.add_mutually_exclusive_group()
#group.add_argument("-v", "--verbose", action="store_true")
#group.add_argument("-q", "--quiet", action="store_true")
#parser.add_argument("x", type=int, help="the base")
#parser.add_argument("y", type=int, help="the exponent")
#args = parser.parse_args()
#answer = args.x**args.y


#FIXME --sum ?
#parser = argparse.ArgumentParser(description='Process some integers.')
#parser.add_argument('integers', metavar='N', type=int, nargs='+',
#                    help='an integer for the accumulator')
#parser.add_argument('--sum', dest='accumulate', action='store_const',
#                    const=sum, default=max,
#                    help='sum the integers (default: find the max)')
#args = parser.parse_args()
#print(args.accumulate(args.integers))


# +++++++++++++++++++++++++++++ nargs
#FIXME longueur fixe
#>>> parser = argparse.ArgumentParser()
#>>> parser.add_argument('--foo', nargs=2)
#>>> parser.add_argument('bar', nargs=1)
#>>> parser.parse_args('c --foo a b'.split())
#Namespace(bar=['c'], foo=['a', 'b'])


#FIXME const
#>>> parser = argparse.ArgumentParser()
#>>> parser.add_argument('--foo', nargs='?', const='c', default='d')
#>>> parser.add_argument('bar', nargs='?', default='d')
#>>> parser.parse_args(['XX', '--foo', 'YY'])
#Namespace(bar='XX', foo='YY')
#>>> parser.parse_args(['XX', '--foo'])
#Namespace(bar='XX', foo='c')
#>>> parser.parse_args([])
#Namespace(bar='d', foo='d')

#FIXME ? | * | +
# * == list
# + == list + mandatory