#!/usr/bin/env fuchsia-vendored-python
# Copyright 2023 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.
"""Verify the runtime dependencies of a prebuilt SDK library (static or shared).
See //build/cpp/verify_runtime_deps.gni for details. This takes two input files:

- A JSON file that lists the runtime dependencies of the library, each
  one of them through a schema described in //build/cpp/verify_runtime_deps.gni

- An SDK manifest file, another JSON file that describes the SDK atom for
  the target as well as _all_ its transitive dependencies. See sdk_atom()
  template for more details.

On success, a stamp file is written. On failure, error messages are printed
to stderr and the script returns with an error status.
"""

import argparse
import collections
import json
import os
import sys

# The following runtime libraries are provided directly by the SDK sysroot,
# and not as SDK atoms.
_SYSROOT_LIBS = ["libc.so", "libzircon.so"]


def parse_sdk_manifest(manifest):
    """Parse SDK manifest file and extract atom id and dependencies.

    Args:
      manifest: A directionary representation of the JSON SDK manifest.

    Returns:
      an (sdk_id, deps) tuple, where 'sdk_id' is a string identifying the
      atom (e.g. 'sdk://pkg/async'), and 'deps' is a dictionary mapping
      the sdk ids of all transitive dependencies to the corresponding
      manifest JSON object.
    """
    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)
    deps = [find_atom(a) for a in atom["deps"]]
    deps += [atom]

    # Maps sdk_ids to the corresponding entry
    deps_map = {dep["id"]: dep for dep in deps}

    return atom_id, deps_map


_NON_SDK_DEPS_ERROR_HEADER = r"""## Non-SDK dependencies required at runtime:
"""

_NON_SDK_DEPS_ERROR_FOOTER = r"""
HINT: These should be defined by an sdk_shared_library() call, or by a
zx_library() one that sets 'sdk = "shared"'.
"""

_BAD_SDK_DEPS_ERROR_HEADER = r"""## Non prebuilt libraries required at runtime:
"""

_BAD_SDK_DEPS_ERROR_FOOTER = _NON_SDK_DEPS_ERROR_FOOTER

_MISSING_SDK_DEPS_ERROR_HEADER = r"""## No dependency generates SDK runtime requirement:
"""

_MISSING_SDK_DEPS_ERROR_FOOTER = r"""
HINT: Add the missing atom(s)'s targets to the 'runtime_deps' list.
"""


class DependencyErrors(object):
    """Models list of errors found during verification."""

    def __init__(self):
        self._errors = []

    def has_error(self):
        """Return True iff this instance contains errors."""
        return bool(self._errors)

    def add_non_sdk_dependency(self, entry):
        """Add an entry for a non-SDK dependency.

        This happens when an SDK atom depends on a shared_library() instance
        directly, instead of an skd_shared_library() one.
        """
        self._errors.append((entry, "non_sdk_deps"))

    def add_bad_sdk_dependency(self, entry):
        """Add an entry for a non-prebuilt shared library."""
        self._errors.append((entry, "bad_sdk_deps"))

    def add_missing_sdk_dependency(self, entry):
        """Add an entry for a non-SDK shared library dependency."""
        self._errors.append((entry, "missing_sdk_deps"))

    def __str__(self):
        result = ""
        # Split errors by categories
        errors = collections.defaultdict(list)
        for entry, category in self._errors:
            errors[category].append(entry)

        for category, entries in errors.items():
            if category == "non_sdk_deps":
                result += _NON_SDK_DEPS_ERROR_HEADER
                for entry in entries:
                    result += "- %s generated_by %s\n" % (
                        entry["source"],
                        entry["label"],
                    )
                result += _NON_SDK_DEPS_ERROR_FOOTER

            elif category == "bad_sdk_deps":
                result += _BAD_SDK_DEPS_ERROR_HEADER
                for entry in entries:
                    result += "- SDK_atom %s generated_by %s\n" % (
                        entry["sdk_id"],
                        entry["label"],
                    )
                result += _BAD_SDK_DEPS_ERROR_FOOTER

            elif category == "missing_sdk_deps":
                result += _MISSING_SDK_DEPS_ERROR_HEADER
                for entry in entries:
                    result += "- SDK_atom %s generated_by %s\n" % (
                        entry["sdk_id"],
                        entry["label"],
                    )
                result += _MISSING_SDK_DEPS_ERROR_FOOTER

            else:
                assert False, "Unknown category: " % category

        return result


def check_missing_files(runtime_files, atom_deps):
    """Verify runtime requirements, and return a DependencyErrors instance."""
    errors = DependencyErrors()

    for entry in runtime_files:
        gn_label = entry["label"]
        sdk_id = entry.get("sdk_id")
        source = entry.get("source")

        assert bool(sdk_id) != bool(source), (
            'Exactly one of "sdk_id" or "source" must be defined in entry: %s'
            % entry
        )

        if sdk_id:
            # This runtime dependency is an SDK library, verify that it is part
            # of the SDK manifest.
            dep = atom_deps.get(sdk_id)
            if not dep:
                errors.add_missing_sdk_dependency(entry)
            elif dep["type"] != "cc_prebuilt_library":
                errors.add_bad_sdk_dependency(entry)
        elif source:
            # Ignore sysroot libs
            if os.path.basename(source) in _SYSROOT_LIBS:
                continue

            # This runtime dependency is *not* an SDK library, this is an error.
            errors.add_non_sdk_dependency(entry)

    return errors


def main():
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument(
        "--sdk-runtime-deps",
        help="Path to the list of runtime deps.",
        required=True,
    )
    parser.add_argument(
        "--sdk-manifest",
        help="Path to the target's SDK manifest file.",
        required=True,
    )
    parser.add_argument(
        "--stamp-file", help="Path to the output stamp file.", required=True
    )
    args = parser.parse_args()

    with open(args.sdk_runtime_deps, "r") as runtime_deps_file:
        runtime_files = json.load(runtime_deps_file)

    # Read the list of package dependencies for the library's SDK incarnation.
    with open(args.sdk_manifest, "r") as manifest_file:
        manifest = json.load(manifest_file)

    atom_id, deps = parse_sdk_manifest(manifest)

    # Find atom label with `_sdk_manifest($toolchain_suffix)` removed
    atom_label, _, _ = deps[atom_id]["gn-label"].rpartition("_sdk_manifest(")

    # Check whether all runtime files are available for packaging.
    errors = check_missing_files(runtime_files, deps)
    if errors.has_error():
        print(
            r"""
ERROR: When verifying runtime dependencies for the SDK atom: %s generated_by %s

%s"""
            % (atom_id, atom_label, errors),
            file=sys.stderr,
        )
        return 1

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

    return 0


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