#!/usr/bin/env python

import commands
import optparse
import os
import os.path
import re
import sys

def extract_exe_symbol_names (arch, exe_path, match_str):
    command = 'dsymutil --arch %s -s "%s" | grep "%s" | colrm 1 69' % (arch, exe_path, match_str)
    (command_exit_status, command_output) = commands.getstatusoutput(command)
    if command_exit_status == 0:
        if command_output:
            return command_output[0:-1].split("'\n")
        else:
            print 'error: command returned no output'
    else:
        print 'error: command failed with exit status %i\n    command: %s' % (command_exit_status, command)
    return list()

def verify_api(all_args):
    '''Verify the API in the specified library is valid given one or more binaries.'''
    usage = "usage: verify_api --library <path> [ --library <path> ...] executable1 [executable2 ...]"
    description='''Verify the API in the specified library is valid given one or more binaries.
    
    Example:
    
        verify_api.py --library ~/Documents/src/lldb/build/Debug/LLDB.framework/LLDB --arch x86_64 /Applications/Xcode.app/Contents/PlugIns/DebuggerLLDB.ideplugin/Contents/MacOS/DebuggerLLDB --api-regex lldb
    '''
    parser = optparse.OptionParser(description=description, prog='verify_api',usage=usage)
    parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='display verbose debug info', default=False)
    parser.add_option('-a', '--arch', type='string', action='append', dest='archs', help='architecure to use when checking the api')
    parser.add_option('-r', '--api-regex', type='string', dest='api_regex_str', help='Exclude any undefined symbols that do not match this regular expression when searching for missing APIs.')
    parser.add_option('-l', '--library', type='string', action='append', dest='libraries', help='Specify one or more libraries that will contain all needed APIs for the executables.')
    (options, args) = parser.parse_args(all_args)
    
    api_external_symbols = list()
    if options.archs:
        for arch in options.archs:
            for library in options.libraries:
                external_symbols = extract_exe_symbol_names(arch, library, "(     SECT EXT)");
                if external_symbols:
                    for external_symbol in external_symbols:
                        api_external_symbols.append(external_symbol)
                else:
                    sys.exit(1)
    else:
        print 'error: must specify one or more architectures with the --arch option'
        sys.exit(4)
    if options.verbose:
        print "API symbols:"
        for (i, external_symbol) in enumerate(api_external_symbols):
            print "[%u] %s" % (i, external_symbol)
    
    api_regex = None
    if options.api_regex_str:
        api_regex = re.compile(options.api_regex_str)
    
    for arch in options.archs:        
        for exe_path in args:
            print 'Verifying (%s) "%s"...' % (arch, exe_path)
            exe_errors = 0
            undefined_symbols = extract_exe_symbol_names(arch, exe_path, "(     UNDF EXT)");
            for undefined_symbol in undefined_symbols:
                if api_regex:
                    match = api_regex.search(undefined_symbol)
                    if not match:
                        if options.verbose:
                            print 'ignoring symbol: %s' % (undefined_symbol)
                        continue
                if undefined_symbol in api_external_symbols:
                    if options.verbose:
                        print 'verified symbol: %s' % (undefined_symbol)
                else:
                    print 'missing symbol: %s' % (undefined_symbol)
                    exe_errors += 1
            if exe_errors:
                print 'error: missing %u API symbols from %s' % (exe_errors, options.libraries)
            else:
                print 'success'
        
if __name__ == '__main__':
    verify_api(sys.argv[1:])