#!/usr/bin/env python2.7

from __future__ import print_function

import argparse
import difflib
import filecmp
import os
import subprocess
import sys

disassembler = 'objdump'

def keep_line(line):
    """Returns true for lines that should be compared in the disassembly
    output."""
    return "file format" not in line

def disassemble(objfile):
    """Disassemble object to a file."""
    p = subprocess.Popen([disassembler, '-d', objfile],
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
    (out, err) = p.communicate()
    if p.returncode or err:
        print("Disassemble failed: {}".format(objfile))
        sys.exit(1)
    return filter(keep_line, out.split(os.linesep))

def dump_debug(objfile):
    """Dump all of the debug info from a file."""
    p = subprocess.Popen([disassembler, '-WliaprmfsoRt', objfile], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (out, err) = p.communicate()
    if p.returncode or err:
        print("Dump debug failed: {}".format(objfile))
        sys.exit(1)
    return filter(keep_line, out.split(os.linesep))

def first_diff(a, b, fromfile, tofile):
    """Returns the first few lines of a difference, if there is one.  Python
    diff can be very slow with large objects and the most interesting changes
    are the first ones. Truncate data before sending to difflib.  Returns None
    is there is no difference."""

    # Find first diff
    first_diff_idx = None
    for idx, val in enumerate(a):
        if val != b[idx]:
            first_diff_idx = idx
            break

    if first_diff_idx == None:
        # No difference
        return None

    # Diff to first line of diff plus some lines
    context = 3
    diff = difflib.unified_diff(a[:first_diff_idx+context],
                                b[:first_diff_idx+context],
                                fromfile,
                                tofile)
    difference = "\n".join(diff)
    if first_diff_idx + context < len(a):
        difference += "\n*** Diff truncated ***"
    return difference

def compare_object_files(objfilea, objfileb):
    """Compare disassembly of two different files.
       Allowing unavoidable differences, such as filenames.
       Return the first difference if the disassembly differs, or None.
    """
    disa = disassemble(objfilea)
    disb = disassemble(objfileb)
    return first_diff(disa, disb, objfilea, objfileb)

def compare_debug_info(objfilea, objfileb):
    """Compare debug info of two different files.
       Allowing unavoidable differences, such as filenames.
       Return the first difference if the debug info differs, or None.
       If there are differences in the code, there will almost certainly be differences in the debug info too.
    """
    dbga = dump_debug(objfilea)
    dbgb = dump_debug(objfileb)
    return first_diff(dbga, dbgb, objfilea, objfileb)

def compare_exact(objfilea, objfileb):
    """Byte for byte comparison between object files.
       Returns True if equal, False otherwise.
    """
    return filecmp.cmp(objfilea, objfileb)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('objfilea', nargs=1)
    parser.add_argument('objfileb', nargs=1)
    parser.add_argument('-v', '--verbose', action='store_true')
    args = parser.parse_args()
    diff = compare_object_files(args.objfilea[0], args.objfileb[0])
    if diff:
        print("Difference detected")
        if args.verbose:
            print(diff)
        sys.exit(1)
    else:
        print("The same")
