# Copyright 2023 The Bazel Authors. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Rules and macros for collecting LicenseInfo providers."""

load("@rules_license//rules:filtered_rule_kinds.bzl", "aspect_filters")
load(
    "@rules_license//rules:providers.bzl",
    "LicenseInfo",
    "PackageInfo",
)
load("@rules_license//rules_gathering:trace.bzl", "TraceInfo")
load(":to_json.bzl", "labels_to_json", "licenses_to_json", "package_infos_to_json")
load(":user_filtered_rule_kinds.bzl", "user_aspect_filters")

TransitivePackageInfo = provider(
    """Transitive list of all SBOM relevant dependencies.""",
    fields = {
        "top_level_target": "Label: The top level target label we are examining.",
        "license_info": "depset(LicenseInfo)",
        "package_info": "depset(PackageInfo)",
        "packages": "depset(label)",
        "target_under_license": "Label: A target which will be associated with some licenses.",
        "traces": "list(string) - diagnostic for tracing a dependency relationship to a target.",
    },
)

# Singleton instance of nothing present. Each level of the aspect must return something,
# so we use one to save space instead of making a lot of empty ones.
NULL_INFO = TransitivePackageInfo(license_info = depset(), package_info = depset(), packages = depset())

def should_traverse(ctx, attr):
    """Checks if the dependent attribute should be traversed.

    Args:
      ctx: The aspect evaluation context.
      attr: The name of the attribute to be checked.

    Returns:
      True iff the attribute should be traversed.
    """
    k = ctx.rule.kind
    for filters in [aspect_filters, user_aspect_filters]:
        always_ignored = filters.get("*", [])
        if k in filters:
            attr_matches = filters[k]
            if (attr in attr_matches or
                "*" in attr_matches or
                ("_*" in attr_matches and attr.startswith("_")) or
                attr in always_ignored):
                return False

            for m in attr_matches:
                if attr == m:
                    return False
    return True

def _get_transitive_metadata(ctx, trans_license_info, trans_package_info, trans_packages, traces, provider, filter_func):
    """Pulls the transitive data up from attributes we care about.

    Collapses all the TransitivePackageInfo providers from my deps into lists
    that we can then turn into a single TPI.
    """
    attrs = [a for a in dir(ctx.rule.attr)]
    for name in attrs:
        if not filter_func(ctx, name):
            continue
        a = getattr(ctx.rule.attr, name)

        # Make anything singleton into a list for convenience.
        if type(a) != type([]):
            a = [a]
        for dep in a:
            # Ignore anything that isn't a target
            if type(dep) != "Target":
                continue

            # Targets can also include things like input files that won't have the
            # aspect, so we additionally check for the aspect rather than assume
            # it's on all targets.  Even some regular targets may be synthetic and
            # not have the aspect. This provides protection against those outlier
            # cases.
            if provider in dep:
                info = dep[provider]
                if info.license_info:
                    trans_license_info.append(info.license_info)
                if info.package_info:
                    trans_package_info.append(info.package_info)
                if info.packages:
                    trans_packages.append(info.packages)

                if hasattr(info, "traces"):
                    if info.traces:
                        for trace in info.traces:
                            traces.append("(" + ", ".join([str(ctx.label), ctx.rule.kind, name]) + ") -> " + trace)

def gather_package_common(target, ctx, provider_factory, metadata_providers, filter_func):
    """Collect license and other metadata info from myself and my deps.

    Any single target might directly depend on a license, or depend on
    something that transitively depends on a license, or neither.
    This aspect bundles all those into a single provider. At each level, we add
    in new direct license deps found and forward up the transitive information
    collected so far.

    This is a common abstraction for crawling the dependency graph. It is
    parameterized to allow specifying the provider that is populated with
    results. It is configurable to select only a subset of providers. It
    is also configurable to specify which dependency edges should not
    be traced for the purpose of tracing the graph.

    Args:
      target: The target of the aspect.
      ctx: The aspect evaluation context.
      provider_factory: abstracts the provider returned by this aspect
      metadata_providers: a list of other providers of interest
      filter_func: a function that returns true iff the dep edge should be ignored

    Returns:
      provider of parameterized type
    """

    # A hack until https://github.com/bazelbuild/rules_license/issues/89 is
    # fully resolved. If exec is in the bin_dir path, then the current
    # configuration is probably cfg = exec.
    if "-exec" in ctx.bin_dir.path:
        return [NULL_INFO]

    # First we gather my direct license attachments
    licenses = []
    package_info = []
    if ctx.rule.kind == "_license":
        # Don't try to gather licenses from the license rule itself. We'll just
        # blunder into the text file of the license and pick up the default
        # attribute of the package, which we don't want.
        pass
    elif hasattr(ctx.rule.attr, "applicable_licenses"):
        for dep in ctx.rule.attr.applicable_licenses:
            if LicenseInfo in dep:
                licenses.append(dep[LicenseInfo])
            if PackageInfo in dep:
                package_info.depend(dep[LicenseInfo])
    elif hasattr(ctx.rule.attr, "package_metadata"):
        for dep in ctx.rule.attr.package_metadata:
            if LicenseInfo in dep:
                licenses.append(dep[LicenseInfo])
            if PackageInfo in dep:
                package_info.depend(dep[LicenseInfo])

    # Record all the external repos anyway.
    target_name = str(target.label)
    packages = []
    if target_name.startswith("@") and target_name[1] != "/":
        packages.append(target.label)
        # DBG print(str(target.label))

    elif hasattr(ctx.rule.attr, "tags"):
        for tag in ctx.rule.attr.tags:
            if tag.startswith("maven_coordinates="):
                packages.append(target.label)

    # Now gather transitive collection of providers from the targets
    # this target depends upon.
    trans_license_info = []
    trans_package_info = []
    trans_packages = []
    traces = []
    _get_transitive_metadata(ctx, trans_license_info, trans_package_info, trans_packages, traces, provider_factory, filter_func)

    if (not licenses and
        not package_info and
        not packages and
        not trans_license_info and
        not trans_package_info and
        not trans_packages):
        return [NULL_INFO]

    # If this is the target, start the sequence of traces.
    if ctx.attr._trace[TraceInfo].trace and ctx.attr._trace[TraceInfo].trace in str(ctx.label):
        traces = [ctx.attr._trace[TraceInfo].trace]

    # Trim the number of traces accumulated since the output can be quite large.
    # A few representative traces are generally sufficient to identify why a dependency
    # is incorrectly incorporated.
    if len(traces) > 10:
        traces = traces[0:10]

    return [provider_factory(
        target_under_license = target.label,
        license_info = depset(direct = licenses, transitive = trans_license_info),
        package_info = depset(direct = package_info, transitive = trans_package_info),
        packages = depset(direct = packages, transitive = trans_packages),
        traces = traces,
    )]

def _gather_package_impl(target, ctx):
    ret = gather_package_common(
        target,
        ctx,
        TransitivePackageInfo,
        # [ExperimentalMetadataInfo, PackageInfo],
        [PackageInfo],
        should_traverse,
    )

    # print(ret)
    return ret

gather_package_info = aspect(
    doc = """Collects License and Package providers into a single TransitivePackageInfo provider.""",
    implementation = _gather_package_impl,
    attr_aspects = ["*"],
    attrs = {
        "_trace": attr.label(default = "@rules_license//rules:trace_target"),
    },
    provides = [TransitivePackageInfo],
    apply_to_generating_rules = True,
)

def _packages_used_impl(ctx):
    """Write the TransitivePackageInfo as JSON."""
    tpi = ctx.attr.target[TransitivePackageInfo]
    licenses_json = licenses_to_json(tpi.license_info)
    package_info_json = package_infos_to_json(tpi.package_info)
    packages = labels_to_json(tpi.packages.to_list())

    # Create a single dict of all the info.
    main_template = """{{
    "top_level_target": "{top_level_target}",
    "licenses": {licenses},
    "package_info": {package_info},
    "packages": {packages}
    \n}}"""

    content = main_template.format(
        top_level_target = ctx.attr.target.label,
        licenses = licenses_json,
        package_info = package_info_json,
        packages = packages,
    )
    ctx.actions.write(
        output = ctx.outputs.out,
        content = content,
    )

packages_used = rule(
    doc = """Gather transitive package information for a target and write as JSON.""",
    implementation = _packages_used_impl,
    attrs = {
        "target": attr.label(
            aspects = [gather_package_info],
            allow_files = True,
        ),
        "out": attr.output(mandatory = True),
    },
)
