#!/usr/bin/env python3 -u

import glob, os, string, sys, _thread, time
# import difflib
import libxml2

###
#
# This is a "Work in Progress" attempt at a python script to run the
# various regression tests.  The rationale for this is that it should be
# possible to run this on most major platforms, including those (such as
# Windows) which don't support gnu Make.
#
# The script is driven by a parameter file which defines the various tests
# to be run, together with the unique settings for each of these tests.  A
# script for Linux is included (regressions.xml), with comments indicating
# the significance of the various parameters.  To run the tests under Windows,
# edit regressions.xml and remove the comment around the default parameter
# "<execpath>" (i.e. make it point to the location of the binary executables).
#
# Note that this current version requires the Python bindings for libxml2 to
# have been previously installed and accessible
#
# See Copyright for the status of this software.
# William Brack (wbrack@mmm.com.hk)
#
###
defaultParams = {}	# will be used as a dictionary to hold the parsed params

# This routine is used for comparing the expected stdout / stdin with the results.
# The expected data has already been read in; the result is a file descriptor.
# Within the two sets of data, lines may begin with a path string.  If so, the
# code "relativises" it by removing the path component.  The first argument is a
# list already read in by a separate thread; the second is a file descriptor.
# The two 'base' arguments are to let me "relativise" the results files, allowing
# the script to be run from any directory.
def compFiles(res, expected, base1, base2):
    l1 = len(base1)
    exp = expected.readlines()
    expected.close()
    # the "relativisation" is done here
    for i in range(len(res)):
        j = string.find(res[i],base1)
        if (j == 0) or ((j == 2) and (res[i][0:2] == './')):
            col = string.find(res[i],':')
            if col > 0:
                start = string.rfind(res[i][:col], '/')
                if start > 0:
                    res[i] = res[i][start+1:]

    for i in range(len(exp)):
        j = string.find(exp[i],base2)
        if (j == 0) or ((j == 2) and (exp[i][0:2] == './')):
            col = string.find(exp[i],':')
            if col > 0:
                start = string.rfind(exp[i][:col], '/')
                if start > 0:
                    exp[i] = exp[i][start+1:]

    ret = 0
    # ideally we would like to use difflib functions here to do a
    # nice comparison of the two sets.  Unfortunately, during testing
    # (using python 2.3.3 and 2.3.4) the following code went into
    # a dead loop under windows.  I'll pursue this later.
#    diff = difflib.ndiff(res, exp)
#    diff = list(diff)
#    for line in diff:
#        if line[:2] != '  ':
#            print string.strip(line)
#            ret = -1

    # the following simple compare is fine for when the two data sets
    # (actual result vs. expected result) are equal, which should be true for
    # us.  Unfortunately, if the test fails it's not nice at all.
    rl = len(res)
    el = len(exp)
    if el != rl:
        print('Length of expected is %d, result is %d' % (el, rl))
	ret = -1
    for i in range(min(el, rl)):
        if string.strip(res[i]) != string.strip(exp[i]):
            print('+:%s-:%s' % (res[i], exp[i]))
            ret = -1
    if el > rl:
        for i in range(rl, el):
            print('-:%s' % exp[i])
            ret = -1
    elif rl > el:
        for i in range (el, rl):
            print('+:%s' % res[i])
            ret = -1
    return ret

# Separate threads to handle stdout and stderr are created to run this function
def readPfile(file, list, flag):
    data = file.readlines()	# no call by reference, so I cheat
    for l in data:
        list.append(l)
    file.close()
    flag.append('ok')

# This routine runs the test program (e.g. xmllint)
def runOneTest(testDescription, filename, inbase, errbase):
    if 'execpath' in testDescription:
        dir = testDescription['execpath'] + '/'
    else:
        dir = ''
    cmd = os.path.abspath(dir + testDescription['testprog'])
    if 'flag' in testDescription:
        for f in string.split(testDescription['flag']):
            cmd += ' ' + f
    if 'stdin' not in testDescription:
        cmd += ' ' + inbase + filename
    if 'extarg' in testDescription:
        cmd += ' ' + testDescription['extarg']

    noResult = 0
    expout = None
    if 'resext' in testDescription:
        if testDescription['resext'] == 'None':
            noResult = 1
        else:
            ext = '.' + testDescription['resext']
    else:
        ext = ''
    if not noResult:
        try:
            fname = errbase + filename + ext
            expout = open(fname, 'rt')
        except:
            print("Can't open result file %s - bypassing test" % fname)
            return

    noErrors = 0
    if 'reserrext' in testDescription:
        if testDescription['reserrext'] == 'None':
            noErrors = 1
        else:
            if len(testDescription['reserrext'])>0:
                ext = '.' + testDescription['reserrext']
            else:
                ext = ''
    else:
        ext = ''
    if not noErrors:
        try:
            fname = errbase + filename + ext
            experr = open(fname, 'rt')
        except:
            experr = None
    else:
        experr = None

    pin, pout, perr = os.popen3(cmd)
    if 'stdin' in testDescription:
        infile = open(inbase + filename, 'rt')
        pin.writelines(infile.readlines())
        infile.close()
        pin.close()

    # popen is great fun, but can lead to the old "deadly embrace", because
    # synchronizing the writing (by the task being run) of stdout and stderr
    # with respect to the reading (by this task) is basically impossible.  I
    # tried several ways to cheat, but the only way I have found which works
    # is to do a *very* elementary multi-threading approach.  We can only hope
    # that Python threads are implemented on the target system (it's okay for
    # Linux and Windows)

    th1Flag = []	# flags to show when threads finish
    th2Flag = []
    outfile = []	# lists to contain the pipe data
    errfile = []
    th1 = _thread.start_new_thread(readPfile, (pout, outfile, th1Flag))
    th2 = _thread.start_new_thread(readPfile, (perr, errfile, th2Flag))
    while (len(th1Flag)==0) or (len(th2Flag)==0):
        time.sleep(0.001)
    if not noResult:
        ret = compFiles(outfile, expout, inbase, 'test/')
        if ret != 0:
            print('trouble with %s' % cmd)
    else:
        if len(outfile) != 0:
            for l in outfile:
                print(l)
            print('trouble with %s' % cmd)
    if experr != None:
        ret = compFiles(errfile, experr, inbase, 'test/')
        if ret != 0:
            print('trouble with %s' % cmd)
    else:
        if not noErrors:
            if len(errfile) != 0:
                for l in errfile:
                    print(l)
                print('trouble with %s' % cmd)

    if 'stdin' not in testDescription:
        pin.close()

# This routine is called by the parameter decoding routine whenever the end of a
# 'test' section is encountered.  Depending upon file globbing, a large number of
# individual tests may be run.
def runTest(description):
    testDescription = defaultParams.copy()		# set defaults
    testDescription.update(description)			# override with current ent
    if 'testname' in testDescription:
        print("## %s" % testDescription['testname'])
    if not 'file' in testDescription:
        print("No file specified - can't run this test!")
        return
    # Set up the source and results directory paths from the decoded params
    dir = ''
    if 'srcdir' in testDescription:
        dir += testDescription['srcdir'] + '/'
    if 'srcsub' in testDescription:
        dir += testDescription['srcsub'] + '/'

    rdir = ''
    if 'resdir' in testDescription:
        rdir += testDescription['resdir'] + '/'
    if 'ressub' in testDescription:
        rdir += testDescription['ressub'] + '/'

    testFiles = glob.glob(os.path.abspath(dir + testDescription['file']))
    if testFiles == []:
        print("No files result from '%s'" % testDescription['file'])
        return

    # Some test programs just don't work (yet).  For now we exclude them.
    count = 0
    excl = []
    if 'exclfile' in testDescription:
        for f in string.split(testDescription['exclfile']):
            glb = glob.glob(dir + f)
            for g in glb:
                excl.append(os.path.abspath(g))

    # Run the specified test program
    for f in testFiles:
        if not os.path.isdir(f):
            if f not in excl:
                count = count + 1
                runOneTest(testDescription, os.path.basename(f), dir, rdir)

#
# The following classes are used with the xmlreader interface to interpret the
# parameter file.  Once a test section has been identified, runTest is called
# with a dictionary containing the parsed results of the interpretation.
#

class testDefaults:
    curText = ''	# accumulates text content of parameter

    def addToDict(self, key):
        txt = string.strip(self.curText)
#        if txt == '':
#            return
        if key not in defaultParams:
            defaultParams[key] = txt
        else:
            defaultParams[key] += ' ' + txt
        
    def processNode(self, reader, curClass):
        if reader.Depth() == 2:
            if reader.NodeType() == 1:
                self.curText = ''	# clear the working variable
            elif reader.NodeType() == 15:
                if (reader.Name() != '#text') and (reader.Name() != '#comment'):
                    self.addToDict(reader.Name())
        elif reader.Depth() == 3:
            if reader.Name() == '#text':
                self.curText += reader.Value()

        elif reader.NodeType() == 15:	# end of element
            print("Defaults have been set to:")
            for k in list(defaultParams.keys()):
                print("   %s : '%s'" % (k, defaultParams[k]))
            curClass = rootClass()
        return curClass


class testClass:
    def __init__(self):
        self.testParams = {}	# start with an empty set of params
        self.curText = ''	# and empty text

    def addToDict(self, key):
        data = string.strip(self.curText)
        if key not in self.testParams:
            self.testParams[key] = data
        else:
            if self.testParams[key] != '':
                data = ' ' + data
            self.testParams[key] += data

    def processNode(self, reader, curClass):
        if reader.Depth() == 2:
            if reader.NodeType() == 1:
                self.curText = ''	# clear the working variable
                if reader.Name() not in self.testParams:
                    self.testParams[reader.Name()] = ''
            elif reader.NodeType() == 15:
                if (reader.Name() != '#text') and (reader.Name() != '#comment'):
                    self.addToDict(reader.Name())
        elif reader.Depth() == 3:
            if reader.Name() == '#text':
                self.curText += reader.Value()

        elif reader.NodeType() == 15:	# end of element
            runTest(self.testParams)
            curClass = rootClass()
        return curClass


class rootClass:
    def processNode(self, reader, curClass):
        if reader.Depth() == 0:
            return curClass
        if reader.Depth() != 1:
            print("Unexpected junk: Level %d, type %d, name %s" % (
                  reader.Depth(), reader.NodeType(), reader.Name()))
            return curClass
        if reader.Name() == 'test':
            curClass = testClass()
            curClass.testParams = {}
        elif reader.Name() == 'defaults':
            curClass = testDefaults()
        return curClass

def streamFile(filename):
    try:
        reader = libxml2.newTextReaderFilename(filename)
    except:
        print("unable to open %s" % (filename))
        return

    curClass = rootClass()
    ret = reader.Read()
    while ret == 1:
        curClass = curClass.processNode(reader, curClass)
        ret = reader.Read()

    if ret != 0:
        print("%s : failed to parse" % (filename))

# OK, we're finished with all the routines.  Now for the main program:-
if len(sys.argv) != 2:
    print("Usage: maketest {filename}")
    sys.exit(-1)

streamFile(sys.argv[1])
