#!/usr/bin/env python

import subprocess
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) = subprocess.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:])
