#!/usr/bin/env python3

import fnmatch
import pathlib
import subprocess
import sys


def lib_name(path):
    return path.name.split('.', 1)[0]


def list_library_names(libs_dirs):
    lib_names = set()

    for libs_dir in libs_dirs:
        libs_path = pathlib.Path(libs_dir)

        for lib_file in libs_path.glob('*.so.libs'):
            # Example: pyobjus.cpython-38-darwin.so.libs
            lib_names.add(lib_name(lib_file))

    return lib_names


def get_current_build_root(libs_dir):
    current_path = pathlib.Path(libs_dir)

    while(
        not fnmatch.fnmatch(current_path.name, 'lib.*')
        and current_path.name != ''  # Emergency exit
    ):
        current_path = current_path.parent

    build_dir = current_path.parent
    assert build_dir.name == 'build'  # Sanity check
    return build_dir


def main():
    target_library, lib_dirs = sys.argv[1], sys.argv[2:]
    print(
        f'Biglink will create library "{target_library}" '
        'from dirs:\n{}'.format("\n".join(lib_dirs))
    )

    lib_names = list_library_names(lib_dirs)
    build_root = get_current_build_root(lib_dirs[0])
    lib_dir = next(build_root.glob('lib.*'))
    target_object_files = set()

    for object_file in lib_dir.rglob('*.so.o'):
        if not object_file.with_suffix('.libs').exists():
            continue

        object_lib = lib_name(object_file)

        if object_lib in lib_names:
            target_object_files.add(str(object_file))
            lib_names.remove(object_lib)

            if not lib_names:
                # We found everything we need
                break

    # ... or maybe we didn't
    assert not lib_names, (
        f'We should have consumed all lib_names but {lib_names} remains'
    )

    command = ['ar', '-q', target_library, *target_object_files]
    print(f'Biglink: running "{" ".join(command)}"')
    subprocess.run(command)


if __name__ == '__main__':
    main()
