# 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
#
#    http://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.

"""
Definition of JavaPluginInfo provider.
"""

java_common = _builtins.toplevel.java_common

_JavaPluginDataInfo = provider(
    doc = "Provider encapsulating information about a Java compatible plugin.",
    fields = {
        "processor_classes": "depset(str) The fully qualified classnames of entry points for the compiler",
        "processor_jars": "depset(file) Deps containing an annotation processor",
        "processor_data": "depset(file) Files needed during execution",
    },
)

_EMPTY_PLUGIN_DATA = _JavaPluginDataInfo(
    processor_classes = depset(),
    processor_jars = depset(),
    processor_data = depset(),
)

def _javaplugininfo_init(
        runtime_deps,
        processor_class,
        data = [],
        generates_api = False):
    """ Constructs JavaPluginInfo

    Args:
        runtime_deps: ([JavaInfo]) list of deps containing an annotation
             processor.
        processor_class: (String) The fully qualified class name that the Java
             compiler uses as an entry point to the annotation processor.
        data: (depset[File]) The files needed by this annotation
             processor during execution.
        generates_api: (boolean) Set to true when this annotation processor
            generates API code. Such an annotation processor is applied to a
            Java target before producing its header jars (which contains method
            signatures). When no API plugins are present, header jars are
            generated from the sources, reducing the critical path.
            WARNING: This parameter affects build performance, use it only if
            necessary.

    Returns:
        (JavaPluginInfo)
    """
    java_infos = java_common.merge(runtime_deps)
    processor_data = data if type(data) == "depset" else depset(data)
    plugins = _JavaPluginDataInfo(
        processor_classes = depset([processor_class]) if processor_class else depset(),
        processor_jars = java_infos.transitive_runtime_jars,
        processor_data = processor_data,
    )
    return {
        "plugins": plugins,
        "api_generating_plugins": plugins if generates_api else _EMPTY_PLUGIN_DATA,
        "java_outputs": java_infos.java_outputs,
    }

JavaPluginInfo, _new_javaplugininfo = provider(
    doc = "Provider encapsulating information about Java plugins.",
    fields = {
        "plugins": """
            Returns data about all plugins that a consuming target should apply.
            This is typically either a <code>java_plugin</code> itself or a
            <code>java_library</code> exporting one or more plugins.
            A <code>java_library</code> runs annotation processing with all
            plugins from this field appearing in <code>deps</code> and
            <code>plugins</code> attributes.""",
        "api_generating_plugins": """
            Returns data about API generating plugins defined or exported by
            this target.
            Those annotation processors are applied to a Java target before
            producing its header jars (which contain method signatures). When
            no API plugins are present, header jars are generated from the
            sources, reducing critical path.
            The <code>api_generating_plugins</code> is a subset of
            <code>plugins</code>.""",
        "java_outputs": """
            Returns information about outputs of this Java/Java-like target.
        """,
    },
    init = _javaplugininfo_init,
)

def merge_without_outputs(infos):
    """ Merge plugin information from a list of JavaPluginInfo or JavaInfo

    Args:
        infos: ([JavaPluginInfo|JavaInfo]) list of providers to merge

    Returns:
        (JavaPluginInfo)
    """
    plugins = []
    api_generating_plugins = []
    for info in infos:
        if _has_plugin_data(info.plugins):
            plugins.append(info.plugins)
        if _has_plugin_data(info.api_generating_plugins):
            api_generating_plugins.append(info.api_generating_plugins)
    return _new_javaplugininfo(
        plugins = _merge_plugin_data(plugins),
        api_generating_plugins = _merge_plugin_data(api_generating_plugins),
        java_outputs = [],
    )

def _has_plugin_data(plugin_data):
    return plugin_data and (
        plugin_data.processor_classes or
        plugin_data.processor_jars or
        plugin_data.processor_data
    )

def _merge_plugin_data(datas):
    return _JavaPluginDataInfo(
        processor_classes = depset(transitive = [p.processor_classes for p in datas]),
        processor_jars = depset(transitive = [p.processor_jars for p in datas]),
        processor_data = depset(transitive = [p.processor_data for p in datas]),
    )
