# Copyright 2021 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.

"""cc_test Starlark implementation."""

load(":common/cc/cc_binary.bzl", "cc_binary_impl")
load(":common/paths.bzl", "paths")
load(":common/cc/cc_binary_attrs.bzl", "cc_binary_attrs_with_aspects", "cc_binary_attrs_without_aspects")
load(":common/cc/cc_helper.bzl", "cc_helper")
load(":common/cc/semantics.bzl", "semantics")

cc_internal = _builtins.internal.cc_internal
platform_common = _builtins.toplevel.platform_common
testing = _builtins.toplevel.testing

def _cc_test_impl(ctx):
    binary_info, cc_info, providers = cc_binary_impl(ctx, [])
    test_env = {}
    test_env.update(cc_helper.get_expanded_env(ctx, {}))

    coverage_runfiles, coverage_env = semantics.get_coverage_env(ctx)

    runfiles_list = [binary_info.runfiles]
    if coverage_runfiles:
        runfiles_list.append(coverage_runfiles)

    runfiles = ctx.runfiles()
    runfiles = runfiles.merge_all(runfiles_list)

    test_env.update(coverage_env)
    providers.append(testing.TestEnvironment(
        environment = test_env,
        inherited_environment = ctx.attr.env_inherit,
    ))
    providers.append(DefaultInfo(
        files = binary_info.files,
        runfiles = runfiles,
        executable = binary_info.executable,
    ))

    if cc_helper.has_target_constraints(ctx, ctx.attr._apple_constraints):
        # When built for Apple platforms, require the execution to be on a Mac.
        providers.append(testing.ExecutionInfo({"requires-darwin": ""}))
    return _handle_legacy_return(ctx, cc_info, providers)

def _handle_legacy_return(ctx, cc_info, providers):
    if ctx.fragments.cpp.enable_legacy_cc_provider():
        # buildifier: disable=rule-impl-return
        return struct(
            cc = cc_internal.create_cc_provider(cc_info = cc_info),
            providers = providers,
        )
    else:
        return providers

def _impl(ctx):
    if semantics.should_use_legacy_cc_test(ctx):
        # This is the "legacy" cc_test flow
        return _cc_test_impl(ctx)

    cc_test_info = ctx.attr._test_toolchain.cc_test_info

    binary_info, cc_info, providers = cc_binary_impl(ctx, cc_test_info.linkopts)
    processed_environment = cc_helper.get_expanded_env(ctx, {})

    test_providers = cc_test_info.get_runner.func(
        ctx,
        binary_info,
        processed_environment = processed_environment,
        **cc_test_info.get_runner.args
    )
    providers.extend(test_providers)
    return _handle_legacy_return(ctx, cc_info, providers)

def make_cc_test(with_linkstatic = False, with_aspects = False):
    """Makes one of the cc_test rule variants.

    This function shall only be used internally in CC ruleset.

    Args:
      with_linkstatic: sets value _linkstatic_explicitly_set attribute
      with_aspects: Attaches graph_structure_aspect to `deps` attribute and
        implicit deps.
    Returns:
      A cc_test rule class.
    """
    _cc_test_attrs = None
    if with_aspects:
        _cc_test_attrs = dict(cc_binary_attrs_with_aspects)
    else:
        _cc_test_attrs = dict(cc_binary_attrs_without_aspects)

    # Update cc_test defaults:
    _cc_test_attrs.update(
        _is_test = attr.bool(default = True),
        _apple_constraints = attr.label_list(
            default = [
                "@" + paths.join(semantics.get_platforms_root(), "os:ios"),
                "@" + paths.join(semantics.get_platforms_root(), "os:macos"),
                "@" + paths.join(semantics.get_platforms_root(), "os:tvos"),
                "@" + paths.join(semantics.get_platforms_root(), "os:watchos"),
            ],
        ),
        _windows_constraints = attr.label_list(
            default = [
                "@" + paths.join(semantics.get_platforms_root(), "os:windows"),
            ],
        ),
        # Starlark tests don't get `env_inherit` by default.
        env_inherit = attr.string_list(),
        stamp = attr.int(values = [-1, 0, 1], default = 0),
        linkstatic = attr.bool(default = False),
    )
    _cc_test_attrs.update(semantics.get_test_malloc_attr())
    _cc_test_attrs.update(semantics.get_test_toolchain_attr())
    _cc_test_attrs.update(semantics.get_coverage_attrs())

    _cc_test_attrs.update(
        _linkstatic_explicitly_set = attr.bool(default = with_linkstatic),
    )
    return rule(
        implementation = _impl,
        attrs = _cc_test_attrs,
        outputs = {
            # TODO(b/198254254): Handle case for windows.
            "stripped_binary": "%{name}.stripped",
            "dwp_file": "%{name}.dwp",
        },
        fragments = ["google_cpp", "cpp", "coverage"],
        exec_groups = {
            "cpp_link": exec_group(copy_from_rule = True),
        },
        toolchains = cc_helper.use_cpp_toolchain() +
                     semantics.get_runtimes_toolchain(),
        incompatible_use_toolchain_transition = True,
        test = True,
    )
