#!/usr/bin/env python3
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
"""Creates an import library from an import description file."""
import ast
import logging
import optparse
import os
import os.path
import shutil
import subprocess
import sys
import tempfile

_USAGE = """\
Usage: %prog [options] [imports-file]

Creates an import library from imports-file.

Note: this script uses the microsoft assembler (ml.exe) and the library tool
    (lib.exe), both of which must be in path.
"""

_ASM_STUB_HEADER = """\
; This file is autogenerated by create_importlib_win.py, do not edit.
.386
.MODEL FLAT, C
.CODE

; Stubs to provide mangled names to lib.exe for the
; correct generation of import libs.
"""

_DEF_STUB_HEADER = """\
; This file is autogenerated by create_importlib_win.py, do not edit.

; Export declarations for generating import libs.
"""

_LOGGER = logging.getLogger()


class _Error(Exception):
    pass


class _ImportLibraryGenerator(object):

    def __init__(self, temp_dir):
        self._temp_dir = temp_dir

    def _Shell(self, cmd, **kw):
        ret = subprocess.call(cmd, **kw)
        _LOGGER.info('Running "%s" returned %d.', cmd, ret)
        if ret != 0:
            raise _Error('Command "%s" returned %d.' % (cmd, ret))

    def _ReadImportsFile(self, imports_file):
        # Slurp the imports file.
        return ast.literal_eval(open(imports_file).read())

    def _WriteStubsFile(self, import_names, output_file):
        output_file.write(_ASM_STUB_HEADER)

        for name in import_names:
            output_file.write('%s PROC\n' % name)
            output_file.write('%s ENDP\n' % name)

        output_file.write('END\n')

    def _WriteDefFile(self, dll_name, import_names, output_file):
        output_file.write(_DEF_STUB_HEADER)
        output_file.write('NAME %s\n' % dll_name)
        output_file.write('EXPORTS\n')
        for name in import_names:
            name = name.split('@')[0]
            output_file.write('  %s\n' % name)

    def _CreateObj(self, dll_name, imports):
        """Writes an assembly file containing empty declarations.

    For each imported function of the form:

    AddClipboardFormatListener@4 PROC
    AddClipboardFormatListener@4 ENDP

    The resulting object file is then supplied to lib.exe with a .def file
    declaring the corresponding non-adorned exports as they appear on the
    exporting DLL, e.g.

    EXPORTS
      AddClipboardFormatListener

    In combination, the .def file and the .obj file cause lib.exe to generate
    an x86 import lib with public symbols named like
    "__imp__AddClipboardFormatListener@4", binding to exports named like
    "AddClipboardFormatListener".

    All of this is perpetrated in a temporary directory, as the intermediate
    artifacts are quick and easy to produce, and of no interest to anyone
    after the fact."""

        # Create an .asm file to provide stdcall-like stub names to lib.exe.
        asm_name = dll_name + '.asm'
        _LOGGER.info('Writing asm file "%s".', asm_name)
        with open(os.path.join(self._temp_dir, asm_name), 'wb') as stubs_file:
            self._WriteStubsFile(imports, stubs_file)

        # Invoke on the assembler to compile it to .obj.
        obj_name = dll_name + '.obj'
        cmdline = ['ml.exe', '/nologo', '/c', asm_name, '/Fo', obj_name]
        self._Shell(cmdline, cwd=self._temp_dir, stdout=open(os.devnull))

        return obj_name

    def _CreateImportLib(self, dll_name, imports, architecture, output_file):
        """Creates an import lib binding imports to dll_name for architecture.

    On success, writes the import library to output file.
    """
        obj_file = None

        # For x86 architecture we have to provide an object file for correct
        # name mangling between the import stubs and the exported functions.
        if architecture == 'x86':
            obj_file = self._CreateObj(dll_name, imports)

        # Create the corresponding .def file. This file has the non stdcall-adorned
        # names, as exported by the destination DLL.
        def_name = dll_name + '.def'
        _LOGGER.info('Writing def file "%s".', def_name)
        with open(os.path.join(self._temp_dir, def_name), 'wb') as def_file:
            self._WriteDefFile(dll_name, imports, def_file)

        # Invoke on lib.exe to create the import library.
        # We generate everything into the temporary directory, as the .exp export
        # files will be generated at the same path as the import library, and we
        # don't want those files potentially gunking the works.
        dll_base_name, ext = os.path.splitext(dll_name)
        lib_name = dll_base_name + '.lib'
        cmdline = [
            'lib.exe',
            '/machine:%s' % architecture,
            '/def:%s' % def_name,
            '/out:%s' % lib_name
        ]
        if obj_file:
            cmdline.append(obj_file)

        self._Shell(cmdline, cwd=self._temp_dir, stdout=open(os.devnull))

        # Copy the .lib file to the output directory.
        shutil.copyfile(os.path.join(self._temp_dir, lib_name), output_file)
        _LOGGER.info('Created "%s".', output_file)

    def CreateImportLib(self, imports_file, output_file):
        # Read the imports file.
        imports = self._ReadImportsFile(imports_file)

        # Creates the requested import library in the output directory.
        self._CreateImportLib(imports['dll_name'], imports['imports'],
                              imports.get('architecture', 'x86'), output_file)


def main():
    parser = optparse.OptionParser(usage=_USAGE)
    parser.add_option(
        '-o', '--output-file', help='Specifies the output file path.')
    parser.add_option(
        '-k',
        '--keep-temp-dir',
        action='store_true',
        help='Keep the temporary directory.')
    parser.add_option(
        '-v', '--verbose', action='store_true', help='Verbose logging.')

    options, args = parser.parse_args()

    if len(args) != 1:
        parser.error('You must provide an imports file.')

    if not options.output_file:
        parser.error('You must provide an output file.')

    options.output_file = os.path.abspath(options.output_file)

    if options.verbose:
        logging.basicConfig(level=logging.INFO)
    else:
        logging.basicConfig(level=logging.WARN)

    temp_dir = tempfile.mkdtemp()
    _LOGGER.info('Created temporary directory "%s."', temp_dir)
    try:
        # Create a generator and create the import lib.
        generator = _ImportLibraryGenerator(temp_dir)

        ret = generator.CreateImportLib(args[0], options.output_file)
    except Exception, e:
        _LOGGER.exception('Failed to create import lib.')
        ret = 1
    finally:
        if not options.keep_temp_dir:
            shutil.rmtree(temp_dir)
            _LOGGER.info('Deleted temporary directory "%s."', temp_dir)

    return ret


if __name__ == '__main__':
    sys.exit(main())
