#!/usr/bin/env python

import subprocess

def splitArgs(s):
    it = iter(s)
    current = ''
    inQuote = False
    for c in it:
        if c == '"':
            if inQuote:
                inQuote = False
                yield current + '"'
            else:
                inQuote = True
                current = '"'
        elif inQuote:
            if c == '\\':
                current += c
                current += it.next()
            else:
                current += c
        elif not c.isspace():
            yield c

def insertMinimumPadding(a, b, dist):
    """insertMinimumPadding(a,b) -> (a',b')

    Return two lists of equal length, where some number of Nones have
    been inserted into the shorter list such that sum(map(dist, a',
    b')) is minimized.

    Assumes dist(X, Y) -> int and non-negative.
    """
    
    def cost(a, b):
        return sum(map(dist, a + [None] * (len(b) - len(a)), b))

    # Normalize so a is shortest.
    if len(b) < len(a):
        b, a = insertMinimumPadding(b, a, dist)
        return a,b

    # For each None we have to insert...
    for i in range(len(b) - len(a)):
        # For each position we could insert it...
        current = cost(a, b)
        best = None
        for j in range(len(a) + 1):
            a_0 = a[:j] + [None] + a[j:]
            candidate = cost(a_0, b)
            if best is None or candidate < best[0]:
                best = (candidate, a_0, j)
        a = best[1]
    return a,b

class ZipperDiff(object):
    """ZipperDiff - Simple (slow) diff only accommodating inserts."""
    
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def dist(self, a, b):
        return a != b

    def getDiffs(self):
        a,b =  insertMinimumPadding(self.a, self.b, self.dist)
        for aElt,bElt in zip(a,b):
            if self.dist(aElt, bElt):
                yield aElt,bElt

class DriverZipperDiff(ZipperDiff):
    def isTempFile(self, filename):
        if filename[0] != '"' or filename[-1] != '"':
            return False
        return (filename.startswith('/tmp/', 1) or
                filename.startswith('/var/', 1))

    def dist(self, a, b):
        if a and b and self.isTempFile(a) and self.isTempFile(b):
            return 0
        return super(DriverZipperDiff, self).dist(a,b)        

class CompileInfo:
    def __init__(self, out, err, res):
        self.commands = []
        
        # Standard out isn't used for much.
        self.stdout = out
        self.stderr = ''

        # FIXME: Compare error messages as well.
        for ln in err.split('\n'):
            if (ln == 'Using built-in specs.' or
                ln.startswith('Target: ') or
                ln.startswith('Configured with: ') or
                ln.startswith('Thread model: ') or
                ln.startswith('gcc version') or
                ln.startswith('clang version')):
                pass
            elif ln.strip().startswith('"'):
                self.commands.append(list(splitArgs(ln)))
            else:
                self.stderr += ln + '\n'
        
        self.stderr = self.stderr.strip()
        self.exitCode = res

def captureDriverInfo(cmd, args):
    p = subprocess.Popen([cmd,'-###'] + args,
                         stdin=None,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    out,err = p.communicate()
    res = p.wait()
    return CompileInfo(out,err,res)

def main():
    import os, sys

    args = sys.argv[1:]
    driverA = os.getenv('DRIVER_A') or 'gcc'
    driverB = os.getenv('DRIVER_B') or 'clang'

    infoA = captureDriverInfo(driverA, args)
    infoB = captureDriverInfo(driverB, args)

    differ = False

    # Compare stdout.
    if infoA.stdout != infoB.stdout:
        print '-- STDOUT DIFFERS -'
        print 'A OUTPUT: ',infoA.stdout
        print 'B OUTPUT: ',infoB.stdout
        print

        diff = ZipperDiff(infoA.stdout.split('\n'),
                          infoB.stdout.split('\n'))
        for i,(aElt,bElt) in enumerate(diff.getDiffs()):
            if aElt is None:
                print 'A missing: %s' % bElt
            elif bElt is None:
                print 'B missing: %s' % aElt
            else:
                print 'mismatch: A: %s' % aElt
                print '          B: %s' % bElt

        differ = True

    # Compare stderr.
    if infoA.stderr != infoB.stderr:
        print '-- STDERR DIFFERS -'
        print 'A STDERR: ',infoA.stderr
        print 'B STDERR: ',infoB.stderr
        print

        diff = ZipperDiff(infoA.stderr.split('\n'),
                          infoB.stderr.split('\n'))
        for i,(aElt,bElt) in enumerate(diff.getDiffs()):
            if aElt is None:
                print 'A missing: %s' % bElt
            elif bElt is None:
                print 'B missing: %s' % aElt
            else:
                print 'mismatch: A: %s' % aElt
                print '          B: %s' % bElt

        differ = True

    # Compare commands.
    for i,(a,b) in enumerate(map(None, infoA.commands, infoB.commands)):
        if a is None:
            print 'A MISSING:',' '.join(b)
            differ = True
            continue
        elif b is None:
            print 'B MISSING:',' '.join(a)
            differ = True
            continue

        diff = DriverZipperDiff(a,b)
        diffs = list(diff.getDiffs())
        if diffs:
            print '-- COMMAND %d DIFFERS -' % i
            print 'A COMMAND:',' '.join(a)
            print 'B COMMAND:',' '.join(b)
            print
            for i,(aElt,bElt) in enumerate(diffs):
                if aElt is None:
                    print 'A missing: %s' % bElt
                elif bElt is None:
                    print 'B missing: %s' % aElt
                else:
                    print 'mismatch: A: %s' % aElt
                    print '          B: %s' % bElt
            differ = True
    
    # Compare result codes.
    if infoA.exitCode != infoB.exitCode:
        print '-- EXIT CODES DIFFER -'
        print 'A: ',infoA.exitCode
        print 'B: ',infoB.exitCode
        differ = True

    if differ:
        sys.exit(1)

if __name__ == '__main__':
    main()
