#!/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 accomodating 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()
