#!/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:])
