# Copyright 2019 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.
"""Bazel Flags."""

load("@bazel_features//private:util.bzl", "lt")  # buildifier: disable=bzl-visibility
load("//rules:utils.bzl", "utils")
load("//rules:visibility.bzl", "PROJECT_VISIBILITY")
load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo")

visibility(PROJECT_VISIBILITY)

_BoolFlagInfo = provider(
    doc = "Provides information about a boolean flag",
    fields = dict(
        name = "flag name",
        value = "flag value",
        explicit = "whether value was set explicitly",
    ),
)
_BoolFlagGroupInfo = provider(
    doc = "Provides information about a boolean flag group",
    fields = dict(
        name = "group name",
        value = "group value",
        flags = "flag names that belong to this group",
    ),
)
_IntFlagInfo = provider(
    doc = "Provides information about an integer flag",
    fields = dict(
        name = "flag name",
        value = "flag value",
    ),
)
FlagsInfo = provider(
    doc = "Provides all flags",
)

def _get_bool(v):
    v = v.lower()
    if v == "true":
        return True
    if v == "false":
        return False
    fail("Unknown bool: " + v)

def _bool_impl(ctx):
    if ctx.label.name in ctx.var:
        value = _get_bool(ctx.var[ctx.label.name])
        return _BoolFlagInfo(
            name = ctx.label.name,
            value = value,
            explicit = True,
        )
    return _BoolFlagInfo(
        name = ctx.label.name,
        value = ctx.attr.default,
        explicit = False,
    )

bool_flag = rule(
    implementation = _bool_impl,
    attrs = dict(
        default = attr.bool(
            mandatory = True,
        ),
        description = attr.string(
            mandatory = True,
        ),
    ),
    provides = [_BoolFlagInfo],
)

def _bool_group_impl(ctx):
    if ctx.label.name in ctx.var:
        value = _get_bool(ctx.var[ctx.label.name])
        return _BoolFlagGroupInfo(
            name = ctx.label.name,
            value = value,
            flags = [f[_BoolFlagInfo].name for f in ctx.attr.flags],
        )
    return _BoolFlagGroupInfo(
        name = ctx.label.name,
        value = ctx.attr.default,
        flags = [f[_BoolFlagInfo].name for f in ctx.attr.flags],
    )

bool_flag_group = rule(
    implementation = _bool_group_impl,
    attrs = dict(
        default = attr.bool(
            mandatory = True,
        ),
        description = attr.string(
            mandatory = True,
        ),
        flags = attr.label_list(
            mandatory = True,
            providers = [_BoolFlagInfo],
        ),
    ),
    provides = [_BoolFlagGroupInfo],
)

def _int_impl(ctx):
    if ctx.label.name in ctx.var:
        value = int(ctx.var[ctx.label.name])
    else:
        value = ctx.attr.default
    return _IntFlagInfo(
        name = ctx.label.name,
        value = value,
    )

int_flag = rule(
    implementation = _int_impl,
    attrs = dict(
        default = attr.int(
            mandatory = True,
        ),
        description = attr.string(
            mandatory = True,
        ),
    ),
    provides = [_IntFlagInfo],
)

def _flags_impl_internal(bool_flags, bool_flag_groups, int_flags):
    flags = dict()

    # For each group, set all flags to the group value
    for fg in bool_flag_groups:
        for f in fg.flags:
            if f in flags:
                fail("Flag '%s' referenced in multiple flag groups" % f)
            flags[f] = fg.value

    # Set booleans
    for b in bool_flags:
        # Always set explicitly specified flags
        if b.explicit:
            flags[b.name] = b.value
            # If not explicit, only set when not set by a group

        elif b.name not in flags:
            flags[b.name] = b.value

    # Set ints
    for i in int_flags:
        flags[i.name] = i.value

    return FlagsInfo(**flags)

def _flags_impl(ctx):
    return _flags_impl_internal(
        utils.collect_providers(_BoolFlagInfo, ctx.attr.targets),
        utils.collect_providers(_BoolFlagGroupInfo, ctx.attr.targets),
        utils.collect_providers(_IntFlagInfo, ctx.attr.targets),
    )

flags_rule = rule(
    implementation = _flags_impl,
    attrs = dict(
        targets = attr.label_list(),
    ),
)

def _flags_macro():
    flags_rule(
        name = "flags",
        targets = native.existing_rules().keys(),
        visibility = ["//visibility:public"],
    )

def _get_flags(ctx):
    flags = ctx.attr._flags
    if type(flags) != "list":
        return flags[FlagsInfo]
    return flags[0][FlagsInfo]

_POSSIBLY_NATIVE_FLAGS = {
    "desugar_java8_libs": (lambda ctx: ctx.fragments.android.desugar_java8_libs, "native"),
}

def read_possibly_native_flag(ctx, flag_name):
    """
    Canonical API for reading a Android build flag.

    Flags might be defined in Starlark or native-Bazel. This function reads flags
    from the correct source based on supporting Bazel version and --incompatible*
    flags that disable native references.

    Args:
        ctx: Rule's configuration context.
        flag_name: Name of the flag to read, without preceding "--".

    Returns:
        The flag's value.
    """

    # Bazel 9.1+ can disable these fragments with --incompatible_remove_ctx_android_fragment.
    # Disabling them means bazel expects Android to read Starlark flags.
    use_native_def = hasattr(ctx.fragments, "android")

    # Developer override to force the Starlark definition for testing.
    # This would allow us to migrate flags gradually from native to Starlark with flag aliases.
    if _POSSIBLY_NATIVE_FLAGS[flag_name][1] == "starlark":
        use_native_def = False

    if lt("9.1.0"):
        use_native_def = True

    if use_native_def:
        return _POSSIBLY_NATIVE_FLAGS[flag_name][0](ctx)
    else:
        # Starlark definition of "--foo" is assumed to be a label dependency named "_foo".
        if hasattr(ctx.attr, "_" + flag_name):
            return getattr(ctx.attr, "_" + flag_name)[BuildSettingInfo].value
        elif hasattr(ctx.fragments, "android"):
            return _POSSIBLY_NATIVE_FLAGS[flag_name][0](ctx)

    fail("Unable to read flag value for " + flag_name)

flags = struct(
    DEFINE_bool = bool_flag,
    DEFINE_bool_group = bool_flag_group,
    DEFINE_int = int_flag,
    FLAGS = _flags_macro,
    FlagsInfo = FlagsInfo,
    get = _get_flags,
)

exported_for_test = struct(
    BoolFlagGroupInfo = _BoolFlagGroupInfo,
    BoolFlagInfo = _BoolFlagInfo,
    IntFlagInfo = _IntFlagInfo,
    bool_impl = _bool_impl,
    flags_impl_internal = _flags_impl_internal,
    int_impl = _int_impl,
)
