# 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, 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 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_internal.CcTestRunnerInfo]

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