# 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("//rules:utils.bzl", "utils")
load("//rules:visibility.bzl", "PROJECT_VISIBILITY")

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]

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,
)
