#!/usr/bin/env python3

import os
import glob
import sys
from MCPL import MCPLError, dump_file
import Core.System as Sys

datadir = os.getenv('SBLD_DATA_DIR')
files = {}
for pkg in ('MCPLTests','MCPLTestsFMT2'):
    for ext in ('.mcpl','.mcpl.gz'):
        for f in glob.glob(os.path.join(datadir,pkg,'*%s'%ext)):
            files['%s/%s'%(pkg,os.path.basename(f))] = f

class RedirectStdout():
    def __init__(self,filename):
        sys.stdout.flush()
        sys.stderr.flush()
        self._f = open(filename, 'w')
        self._true_stdout = sys.stdout
        sys.stdout = self._f
    def __enter__(self):
        return self
    def __exit__(self,*args):
        sys.stdout.flush()
        sys.stderr.flush()
        self._f.close()
        sys.stdout = self._true_stdout
        sys.stdout.flush()
        sys.stderr.flush()

errors = False
for file_key in sorted(files.keys()):
    file_path = files[file_key]
    print("Testing %s"%file_key)
    expect_crash = False
    truncated_file = 'reffile_truncated' in file_key
    if ('crash' in file_key and file_key.endswith('.gz')) or 'reffile_bad' in file_key or truncated_file:
        expect_crash = True
        print(" -- assuming this is a broken file which can't be read without errors")

        #First compare mcpltool-like output:
    with RedirectStdout('dump_pymcpltool.txt'):
        try:
            if truncated_file:
                dump_file(file_path,limit=0,blocklength=1)#need bl=1 to get same output as C-mcpltool
            else:
                dump_file(file_path,limit=0)
            ec=0
        except MCPLError as mpe:
            print('MCPL ERROR: %s'%str(mpe))
            ec=1
    if (ec!=0) !=  expect_crash:
        errors = True
        print("ERRORS DETECTED in python dump (unexpected exception status)")
        continue
    ec,mcpltool_output = Sys.system(Sys.quote_cmd(['sb_mcpl_tool','-l0',file_path]),catch_output=True)
    _py3 = sys.version_info>=(3,)
    with open('dump_mcpltool.txt','wb') as f:
        f.write(mcpltool_output)
    if (ec!=0) !=  expect_crash:
        errors = True
        print("ERRORS DETECTED in mcpltool (unexpected error status)")
        continue
    ec=Sys.system(Sys.quote_cmd(['diff','dump_mcpltool.txt','dump_pymcpltool.txt']))
    if ec!=0:
        errors = True
        print("ERRORS DETECTED in mcpltool-like output")
    #Now compare numbers based on high-res ascii output:
    if expect_crash:
        continue
    Sys.rm_f('dump_ascii_c.txt')
    Sys.rm_f('dump_ascii_py.txt')
    out_c = Sys.system_throw(Sys.quote_cmd(['sb_mcpl_tool','--text',file_path,'dump_ascii_c.txt']),catch_output=True)
    if out_c.strip():
        print(out_c.decode('utf-8') if _py3 else out_c, end='')
    sys.stdout.flush()
    out_py = Sys.system_throw(Sys.quote_cmd(['sb_mcpl_pytool','--text',file_path,'dump_ascii_py.txt']),catch_output=True)
    if out_py.strip():
        print(out_py.decode('utf-8') if _py3 else out_py, end='')
    sys.stdout.flush()
    if out_c!=out_py:
        print("ERRORS DETECTED in stdout during creation of ascii output")
    from MCPLPyTests.checkasciicompat import check_compat
    incompat_errmsg = check_compat('./dump_ascii_c.txt','./dump_ascii_py.txt')
    if incompat_errmsg is not None:
        raise SystemExit('ERRORS DETECTED in high-res ascii output.'
                        f' C and Py tool output differs: {incompat_errmsg}')

sys.exit(1 if errors else 0)
