#!/usr/bin/python

#  Copyright 2016 The WebRTC project authors. All Rights Reserved.
#
#  Use of this source code is governed by a BSD-style license
#  that can be found in the LICENSE file in the root of the source
#  tree. An additional intellectual property rights grant can be found
#  in the file PATENTS.  All contributing project authors may
#  be found in the AUTHORS file in the root of the source tree.
"""Script for merging generated iOS libraries."""

import sys

import argparse
import os
import re
import subprocess

# Valid arch subdir names.
VALID_ARCHS = ['arm_libs', 'arm64_libs', 'ia32_libs', 'x64_libs']


def MergeLibs(lib_base_dir):
    """Merges generated iOS libraries for different archs.

  Uses libtool to generate FAT archive files for each generated library.

  Args:
    lib_base_dir: directory whose subdirectories are named by architecture and
                  contain the built libraries for that architecture

  Returns:
    Exit code of libtool.
  """
    output_dir_name = 'fat_libs'
    archs = [arch for arch in os.listdir(lib_base_dir) if arch in VALID_ARCHS]
    # For each arch, find (library name, libary path) for arch. We will merge
    # all libraries with the same name.
    libs = {}
    for lib_dir in [os.path.join(lib_base_dir, arch) for arch in VALID_ARCHS]:
        if not os.path.exists(lib_dir):
            continue
        for dirpath, _, filenames in os.walk(lib_dir):
            for filename in filenames:
                if not filename.endswith('.a'):
                    continue
                entry = libs.get(filename, [])
                entry.append(os.path.join(dirpath, filename))
                libs[filename] = entry
    orphaned_libs = {}
    valid_libs = {}
    for library, paths in libs.items():
        if len(paths) < len(archs):
            orphaned_libs[library] = paths
        else:
            valid_libs[library] = paths
    for library, paths in orphaned_libs.items():
        components = library[:-2].split('_')[:-1]
        found = False
        # Find directly matching parent libs by stripping suffix.
        while components and not found:
            parent_library = '_'.join(components) + '.a'
            if parent_library in valid_libs:
                valid_libs[parent_library].extend(paths)
                found = True
                break
            components = components[:-1]
        # Find next best match by finding parent libs with the same prefix.
        if not found:
            base_prefix = library[:-2].split('_')[0]
            for valid_lib, valid_paths in valid_libs.items():
                if valid_lib[:len(base_prefix)] == base_prefix:
                    valid_paths.extend(paths)
                    found = True
                    break
        assert found

    # Create output directory.
    output_dir_path = os.path.join(lib_base_dir, output_dir_name)
    if not os.path.exists(output_dir_path):
        os.mkdir(output_dir_path)

    # Use this so libtool merged binaries are always the same.
    env = os.environ.copy()
    env['ZERO_AR_DATE'] = '1'

    # Ignore certain errors.
    libtool_re = re.compile(r'^.*libtool:.*file: .* has no symbols$')

    # Merge libraries using libtool.
    libtool_returncode = 0
    for library, paths in valid_libs.items():
        cmd_list = [
            'libtool', '-static', '-v', '-o',
            os.path.join(output_dir_path, library)
        ] + paths
        libtoolout = subprocess.Popen(cmd_list,
                                      stderr=subprocess.PIPE,
                                      env=env)
        _, err = libtoolout.communicate()
        for line in err.splitlines():
            if not libtool_re.match(line):
                print >> sys.stderr, line
        # Unconditionally touch the output .a file on the command line if present
        # and the command succeeded. A bit hacky.
        libtool_returncode = libtoolout.returncode
        if not libtool_returncode:
            for i in range(len(cmd_list) - 1):
                if cmd_list[i] == '-o' and cmd_list[i + 1].endswith('.a'):
                    os.utime(cmd_list[i + 1], None)
                    break
    return libtool_returncode


def Main():
    parser_description = 'Merge WebRTC libraries.'
    parser = argparse.ArgumentParser(description=parser_description)
    parser.add_argument('lib_base_dir',
                        help='Directory with built libraries. ',
                        type=str)
    args = parser.parse_args()
    lib_base_dir = args.lib_base_dir
    MergeLibs(lib_base_dir)


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