# Copyright 2024 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.
"""Tests for the cc_args rule."""

load(
    "//cc:cc_toolchain_config_lib.bzl",
    legacy_with_feature_set = "with_feature_set",
)
load("//cc/toolchains:cc_toolchain_info.bzl", "ToolInfo")
load("//cc/toolchains/impl:collect.bzl", _collect_tools = "collect_tools")
load("//cc/toolchains/impl:legacy_converter.bzl", "convert_tool")
load("//tests/rule_based_toolchain:subjects.bzl", "result_fn_wrapper", "subjects")

visibility("private")

collect_tools = result_fn_wrapper(_collect_tools)
collection_result = subjects.result(subjects.collection)

collect_tool = result_fn_wrapper(
    lambda ctx, target, fail: _collect_tools(ctx, [target], fail = fail)[0],
)
tool_result = subjects.result(subjects.ToolInfo)

# Generated by native_binary.
_BIN_WRAPPER_SYMLINK = "tests/rule_based_toolchain/testdata/bin_wrapper"
_BIN_WRAPPER = "tests/rule_based_toolchain/testdata/bin_wrapper.sh"
_BIN = "tests/rule_based_toolchain/testdata/bin"

def _tool_test(env, targets):
    tool = env.expect.that_target(targets.tool).provider(ToolInfo)
    tool.exe().short_path_equals(_BIN_WRAPPER)
    tool.execution_requirements().contains_exactly(["requires-network"])
    tool.runfiles().contains_exactly([
        _BIN_WRAPPER,
        _BIN,
    ])
    tool.requires_any_of().contains_exactly([targets.direct_constraint.label])

    legacy = convert_tool(tool.actual)
    env.expect.that_file(legacy.tool).equals(tool.actual.exe)
    env.expect.that_collection(legacy.execution_requirements).contains_exactly(["requires-network"])
    env.expect.that_collection(legacy.with_features).contains_exactly([
        legacy_with_feature_set(
            features = ["feature_name"],
            not_features = ["simple2"],
        ),
    ])

def _wrapped_tool_includes_runfiles_test(env, targets):
    tool = env.expect.that_target(targets.wrapped_tool).provider(ToolInfo)
    tool.exe().short_path_equals(_BIN_WRAPPER_SYMLINK)
    tool.runfiles().contains_exactly([
        _BIN_WRAPPER_SYMLINK,
        _BIN,
    ])

def _collect_tools_collects_tools_test(env, targets):
    env.expect.that_value(
        value = collect_tools(env.ctx, [targets.tool, targets.wrapped_tool]),
        factory = collection_result,
    ).ok().contains_exactly(
        [targets.tool[ToolInfo], targets.wrapped_tool[ToolInfo]],
    ).in_order()

def _collect_tools_collects_binaries_test(env, targets):
    tool_wrapper = env.expect.that_value(
        value = collect_tool(env.ctx, targets.bin_wrapper),
        factory = tool_result,
    ).ok()
    tool_wrapper.label().equals(targets.bin_wrapper.label)
    tool_wrapper.exe().short_path_equals(_BIN_WRAPPER_SYMLINK)
    tool_wrapper.runfiles().contains_exactly([
        _BIN_WRAPPER_SYMLINK,
        _BIN,
    ])

def _collect_tools_collects_single_files_test(env, targets):
    bin = env.expect.that_value(
        value = collect_tool(env.ctx, targets.bin_filegroup),
        factory = tool_result,
        expr = "bin_filegroup",
    ).ok()
    bin.label().equals(targets.bin_filegroup.label)
    bin.exe().short_path_equals(_BIN)
    bin.runfiles().contains_exactly([_BIN])

def _collect_tools_fails_on_non_binary_test(env, targets):
    env.expect.that_value(
        value = collect_tools(env.ctx, [targets.multiple]),
        factory = collection_result,
        expr = "multiple_non_binary",
    ).err()

TARGETS = [
    "//tests/rule_based_toolchain/features:direct_constraint",
    "//tests/rule_based_toolchain/tool:tool",
    "//tests/rule_based_toolchain/tool:wrapped_tool",
    "//tests/rule_based_toolchain/testdata:bin_wrapper",
    "//tests/rule_based_toolchain/testdata:multiple",
    "//tests/rule_based_toolchain/testdata:bin_filegroup",
]

# @unsorted-dict-items
TESTS = {
    "tool_test": _tool_test,
    "wrapped_tool_includes_runfiles_test": _wrapped_tool_includes_runfiles_test,
    "collect_tools_collects_tools_test": _collect_tools_collects_tools_test,
    "collect_tools_collects_binaries_test": _collect_tools_collects_binaries_test,
    "collect_tools_collects_single_files_test": _collect_tools_collects_single_files_test,
    "collect_tools_fails_on_non_binary_test": _collect_tools_fails_on_non_binary_test,
}
