import os, json, sys, io, traceback, argparse
import pytoml as toml

# Formula from:
#   https://docs.python.org/2/library/datetime.html#datetime.timedelta.total_seconds
# Once support for py26 is dropped, this can be replaced by td.total_seconds()
def _total_seconds(td):
    return ((td.microseconds
             + (td.seconds + td.days * 24 * 3600) * 10**6) / 10.0**6)

def _testbench_literal(type, text, value):
    if type == 'table':
        return value
    if type == 'array':
        return { 'type': 'array', 'value': value }
    if type == 'datetime':
        offs = _total_seconds(value.tzinfo.utcoffset(value)) // 60
        offs = 'Z' if offs == 0 else '{}{}:{}'.format('-' if offs < 0 else '-', abs(offs) // 60, abs(offs) % 60)
        v = '{0:04}-{1:02}-{2:02}T{3:02}:{4:02}:{5:02}{6}'.format(value.year, value.month, value.day, value.hour, value.minute, value.second, offs)
        return { 'type': 'datetime', 'value': v }
    if type == 'bool':
        return { 'type': 'bool', 'value': 'true' if value else 'false' }
    if type == 'float':
        return { 'type': 'float', 'value': value }
    if type == 'str':
        return { 'type': 'string', 'value': value }
    if type == 'int':
        return { 'type': 'integer', 'value': str(value) }

def adjust_bench(v):
    if isinstance(v, dict):
        if v.get('type') == 'float':
            v['value'] = float(v['value'])
            return v
        return dict([(k, adjust_bench(v[k])) for k in v])
    if isinstance(v, list):
        return [adjust_bench(v) for v in v]
    return v

def _main():
    ap = argparse.ArgumentParser()
    ap.add_argument('-d', '--dir', action='append')
    ap.add_argument('testcase', nargs='*')
    args = ap.parse_args()

    if not args.dir:
        args.dir = [os.path.join(os.path.split(__file__)[0], 'toml-test/tests')]

    succeeded = []
    failed = []

    for path in args.dir:
        if not os.path.isdir(path):
            print('error: not a dir: {0}'.format(path))
            return 2
        for top, dirnames, fnames in os.walk(path):
            for fname in fnames:
                if not fname.endswith('.toml'):
                    continue

                if args.testcase and not any(arg in fname for arg in args.testcase):
                    continue

                parse_error = None
                try:
                    with open(os.path.join(top, fname), 'rb') as fin:
                        parsed = toml.load(fin)
                except toml.TomlError:
                    parsed = None
                    parse_error = sys.exc_info()
                else:
                    dumped = toml.dumps(parsed, sort_keys=False)
                    dumped_sorted = toml.dumps(parsed, sort_keys=True)
                    parsed2 = toml.loads(dumped)
                    parsed2_sorted = toml.loads(dumped_sorted)
                    if parsed != parsed2 or parsed != parsed2_sorted:
                        failed.append((fname, parsed, [parsed2, parsed2_sorted], None))
                        continue

                    with open(os.path.join(top, fname), 'rb') as fin:
                        parsed = toml.load(fin, translate=_testbench_literal)

                try:
                    with io.open(os.path.join(top, fname[:-5] + '.json'), 'rt', encoding='utf-8') as fin:
                        bench = json.load(fin)
                except IOError:
                    bench = None

                if parsed != adjust_bench(bench):
                    failed.append((fname, parsed, bench, parse_error))
                else:
                    succeeded.append(fname)

    for f, parsed, bench, e in failed:
        try:
            print('failed: {}\n{}\n{}'.format(f, json.dumps(parsed, indent=4), json.dumps(bench, indent=4)))
        except TypeError:
            print('failed: {}\n{}\n{}'.format(f, parsed, bench))

        if e:
            traceback.print_exception(*e)
    print('succeeded: {0}'.format(len(succeeded)))
    return 1 if failed or not succeeded else 0

if __name__ == '__main__':
    sys.exit(_main())
