#!/usr/bin/env python
# Copyright 2018 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import argparse
import json
import os
import sys


def has_packaged_file(needed_file, deps):
    """Returns true if the given file could be found in the given deps."""
    for dep in deps:
        for file in dep['files']:
            if not file['packaged']:
                continue
            if needed_file == os.path.normpath(file['source']):
                return True
    return False


def has_missing_files(runtime_files, package_deps):
    """Returns true if a runtime file is missing from the given deps."""
    has_missing_files = False
    for file in runtime_files:
        # Some libraries are only known to GN as ABI stubs, whereas the real
        # runtime dependency is generated in parallel as a ".so.impl" file.
        if (not has_packaged_file(file, package_deps) and
                not has_packaged_file('%s.impl' % file, package_deps)):
            print('No package dependency generates %s' % file)
            has_missing_files = True
    return has_missing_files


def main():
    parser = argparse.ArgumentParser(
            "Verifies a prebuilt library's runtime dependencies")
    parser.add_argument('--root-out-dir',
                        help='Path to the root output directory',
                        required=True)
    parser.add_argument('--runtime-deps-file',
                        help='Path to the list of runtime deps',
                        required=True)
    parser.add_argument('--manifest',
                        help='Path to the target\'s SDK manifest file',
                        required=True)
    parser.add_argument('--stamp',
                        help='Path to the stamp file to generate',
                        required=True)
    args = parser.parse_args()

    # Read the list of runtime dependencies generated by GN.
    def normalize_dep(dep):
        return os.path.normpath(os.path.join(args.root_out_dir, dep.strip()))
    with open(args.runtime_deps_file, 'r') as runtime_deps_file:
        runtime_files = map(normalize_dep, runtime_deps_file.readlines())

    # Read the list of package dependencies for the library's SDK incarnation.
    with open(args.manifest, 'r') as manifest_file:
        manifest = json.load(manifest_file)
    atom_id = manifest['ids'][0]
    def find_atom(id):
        return next(a for a in manifest['atoms'] if a['id'] == id)
    atom = find_atom(atom_id)
    package_deps = map(lambda a: find_atom(a), atom['package-deps'])

    # Check whether all runtime files are available for packaging.
    if has_missing_files(runtime_files, package_deps):
        return 1

    with open(args.stamp, 'w') as stamp:
        stamp.write('Success!')


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