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

"""Starlark tests for cc_shared_library"""

load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts", "unittest")

def _same_package_or_above(label_a, label_b):
    if label_a.workspace_name != label_b.workspace_name:
        return False
    package_a_tokenized = label_a.package.split("/")
    package_b_tokenized = label_b.package.split("/")
    if len(package_b_tokenized) < len(package_a_tokenized):
        return False

    if package_a_tokenized[0] != "":
        for i in range(len(package_a_tokenized)):
            if package_a_tokenized[i] != package_b_tokenized[i]:
                return False

    return True

def _check_if_target_under_path(value, pattern):
    if pattern.workspace_name != value.workspace_name:
        return False
    if pattern.name == "__pkg__":
        return pattern.package == value.package
    if pattern.name == "__subpackages__":
        return _same_package_or_above(pattern, value)

    return pattern.package == value.package and pattern.name == value.name

def _linking_order_test_impl(ctx):
    env = analysistest.begin(ctx)

    def _filename(path):
        filename = None
        for i in range(len(path) - 1, -1, -1):
            if path[i] == "/":
                filename = path[i + 1:]
                break

        asserts.true(env, filename != None, "the test assumes the argument is a file path")
        return filename

    if ctx.attr.is_linux:
        target_under_test = analysistest.target_under_test(env)
        actions = analysistest.target_actions(env)

        target_action = None
        for action in actions:
            if action.mnemonic == "FileWrite":
                target_action = action
                break
        args = target_action.content.split("\n")
        user_libs = []
        for arg in args:
            if arg.endswith(".o"):
                user_libs.append(_filename(arg))

        asserts.true(env, user_libs.index("foo.pic.o") < user_libs.index("baz.pic.o"), "'foo' should appear before 'bar' in command line")
        asserts.true(env, user_libs[-1] == "a_suffix.pic.o", "liba_suffix.pic.o should be the last user library linked")

    return analysistest.end(env)

linking_order_test = analysistest.make(
    _linking_order_test_impl,
    attrs = {
        "is_linux": attr.bool(),
    },
)

def _additional_inputs_test_impl(ctx):
    env = analysistest.begin(ctx)

    if ctx.attr.is_linux:
        target_under_test = analysistest.target_under_test(env)
        actions = analysistest.target_actions(env)

        found = False
        target_action = None
        for action in actions:
            if action.mnemonic == "CppLink":
                target_action = action
                break
        for arg in target_action.argv:
            if arg.find("-Wl,--script=") != -1:
                asserts.equals(env, "src/main/starlark/tests/builtins_bzl/cc/cc_shared_library/test_cc_shared_library/additional_script.txt", arg[13:])
                found = True
                break
        asserts.true(env, found, "Should have seen option --script=")

    return analysistest.end(env)

additional_inputs_test = analysistest.make(
    _additional_inputs_test_impl,
    attrs = {
        "is_linux": attr.bool(),
    },
)

def _build_failure_test_impl(ctx):
    env = analysistest.begin(ctx)

    if ctx.attr.message:
        asserts.expect_failure(env, ctx.attr.message)

    if ctx.attr.messages:
        for message in ctx.attr.messages:
            asserts.expect_failure(env, message)

    return analysistest.end(env)

build_failure_test = analysistest.make(
    _build_failure_test_impl,
    expect_failure = True,
    attrs = {
        "message": attr.string(),
        "messages": attr.string_list(),
    },
)

def _paths_test_impl(ctx):
    env = unittest.begin(ctx)

    asserts.false(env, _check_if_target_under_path(Label("//foo"), Label("//bar")))
    asserts.false(env, _check_if_target_under_path(Label("@foo//foo"), Label("@bar//bar")))
    asserts.false(env, _check_if_target_under_path(Label("//bar"), Label("@foo//bar")))
    asserts.true(env, _check_if_target_under_path(Label("@foo//bar"), Label("@foo//bar")))
    asserts.true(env, _check_if_target_under_path(Label("@foo//bar:bar"), Label("@foo//bar")))
    asserts.true(env, _check_if_target_under_path(Label("//bar:bar"), Label("//bar")))

    asserts.false(env, _check_if_target_under_path(Label("@foo//bar/baz"), Label("@foo//bar")))
    asserts.false(env, _check_if_target_under_path(Label("@foo//bar/baz"), Label("@foo//bar:__pkg__")))
    asserts.true(env, _check_if_target_under_path(Label("@foo//bar/baz"), Label("@foo//bar:__subpackages__")))
    asserts.true(env, _check_if_target_under_path(Label("@foo//bar:qux"), Label("@foo//bar:__pkg__")))

    asserts.false(env, _check_if_target_under_path(Label("@foo//bar"), Label("@foo//bar/baz:__subpackages__")))
    asserts.false(env, _check_if_target_under_path(Label("//bar"), Label("//bar/baz:__pkg__")))

    asserts.true(env, _check_if_target_under_path(Label("//foo/bar:baz"), Label("//:__subpackages__")))

    return unittest.end(env)

paths_test = unittest.make(_paths_test_impl)

def _runfiles_test_impl(ctx):
    env = analysistest.begin(ctx)
    if not ctx.attr.is_linux:
        return analysistest.end(env)

    target_under_test = analysistest.target_under_test(env)
    expected_suffixes = [
        "libfoo_so.so",
        "libbar_so.so",
        "libdiff_pkg_so.so",
        "libprivate_lib_so.so",
        "Smain_Sstarlark_Stests_Sbuiltins_Ubzl_Scc_Scc_Ushared_Ulibrary_Stest_Ucc_Ushared_Ulibrary_Slibfoo_Uso.so",
        "Smain_Sstarlark_Stests_Sbuiltins_Ubzl_Scc_Scc_Ushared_Ulibrary_Stest_Ucc_Ushared_Ulibrary_Slibbar_Uso.so",
        "Smain_Sstarlark_Stests_Sbuiltins_Ubzl_Scc_Scc_Ushared_Ulibrary_Stest_Ucc_Ushared_Ulibrary3_Slibdiff_Upkg_Uso.so",
        "Smain_Sstarlark_Stests_Sbuiltins_Ubzl_Scc_Scc_Ushared_Ulibrary_Stest_Ucc_Ushared_Ulibrary/renamed_so_file_copy.so",
        "Smain_Sstarlark_Stests_Sbuiltins_Ubzl_Scc_Scc_Ushared_Ulibrary_Stest_Ucc_Ushared_Ulibrary/libdirect_so_file.so",
    ]
    for runfile in target_under_test[DefaultInfo].default_runfiles.files.to_list():
        # Ignore Python runfiles
        if "python" in runfile.path:
            continue
        found_suffix = False
        for expected_suffix in expected_suffixes:
            if runfile.path.endswith(expected_suffix):
                found_suffix = True
                break
        asserts.true(env, found_suffix, runfile.path + " not found in expected suffixes:\n" + "\n".join(expected_suffixes))

    return analysistest.end(env)

runfiles_test = analysistest.make(
    _runfiles_test_impl,
    attrs = {
        "is_linux": attr.bool(),
    },
)

def _interface_library_output_group_test_impl(ctx):
    env = analysistest.begin(ctx)
    if not ctx.attr.is_windows:
        return analysistest.end(env)

    target_under_test = analysistest.target_under_test(env)
    actual_files = []
    for interface_library in target_under_test[OutputGroupInfo].interface_library.to_list():
        actual_files.append(interface_library.basename)
    expected_files = ["foo_so.if.lib"]
    asserts.equals(env, expected_files, actual_files)

    return analysistest.end(env)

interface_library_output_group_test = analysistest.make(
    _interface_library_output_group_test_impl,
    attrs = {
        "is_windows": attr.bool(),
    },
)

def _check_linking_action_lib_parameters_test_impl(ctx):
    env = analysistest.begin(ctx)

    actions = analysistest.target_actions(env)

    target_action = None
    for action in actions:
        if action.mnemonic == "FileWrite":
            target_action = action
            break
    args = target_action.content.split("\n")
    for arg in args:
        for bad_lib_entry in ctx.attr.libs_that_shouldnt_be_present:
            asserts.true(env, arg.find("{}.".format(bad_lib_entry)) == -1, "Should not have seen library `{}` in command line".format(arg))

    return analysistest.end(env)

check_linking_action_lib_parameters_test = analysistest.make(
    _check_linking_action_lib_parameters_test_impl,
    attrs = {
        "libs_that_shouldnt_be_present": attr.string_list(),
    },
)

AspectCcInfo = provider("Takes a cc_info.", fields = {"cc_info": "cc_info"})
WrappedCcInfo = provider("Takes a cc_info.", fields = {"cc_info": "cc_info"})

def _forwarding_cc_lib_aspect_impl(target, ctx):
    cc_info = target[WrappedCcInfo].cc_info
    linker_inputs = []
    owner = ctx.label.relative(ctx.label.name + ".custom")
    for linker_input in cc_info.linking_context.linker_inputs.to_list():
        if linker_input.owner == ctx.label.relative("indirect_dep"):
            linker_inputs.append(cc_common.create_linker_input(
                owner = owner,
                libraries = depset(linker_input.libraries),
            ))
        else:
            linker_inputs.append(linker_input)
    cc_info = CcInfo(
        compilation_context = cc_info.compilation_context,
        linking_context = cc_common.create_linking_context(
            linker_inputs = depset(linker_inputs),
        ),
    )
    return [
        AspectCcInfo(cc_info = cc_info),
        cc_common.CcSharedLibraryHintInfo_6_X_constructor_do_not_use(
            owners = [owner],
        ),
    ]

forwarding_cc_lib_aspect = aspect(
    implementation = _forwarding_cc_lib_aspect_impl,
    required_providers = [WrappedCcInfo],
    provides = [AspectCcInfo, cc_common.CcSharedLibraryHintInfo_6_X_getter_do_not_use],
)

def _wrapped_cc_lib_impl(ctx):
    return [WrappedCcInfo(cc_info = ctx.attr.deps[0][CcInfo]), CcInfo()]

wrapped_cc_lib = rule(
    implementation = _wrapped_cc_lib_impl,
    attrs = {
        "deps": attr.label_list(providers = [CcInfo]),
    },
    provides = [WrappedCcInfo, CcInfo],
)

def _forwarding_cc_lib_impl(ctx):
    hints = cc_common.CcSharedLibraryHintInfo_6_X_constructor_do_not_use(attributes = ["deps"])
    if ctx.attr.deps:
        return [ctx.attr.deps[0][AspectCcInfo].cc_info, hints]
    else:
        return [ctx.attr.do_not_follow_deps[0][AspectCcInfo].cc_info, hints]

forwarding_cc_lib = rule(
    implementation = _forwarding_cc_lib_impl,
    attrs = {
        "deps": attr.label_list(providers = [WrappedCcInfo], aspects = [forwarding_cc_lib_aspect]),
        "do_not_follow_deps": attr.label_list(providers = [WrappedCcInfo], aspects = [forwarding_cc_lib_aspect]),
    },
    provides = [CcInfo, cc_common.CcSharedLibraryHintInfo_6_X_getter_do_not_use],
)

def _nocode_cc_lib_impl(ctx):
    linker_input = cc_common.create_linker_input(
        owner = ctx.label,
        additional_inputs = depset([ctx.files.additional_inputs[0]]),
    )
    cc_info = CcInfo(linking_context = cc_common.create_linking_context(linker_inputs = depset([linker_input])))
    return [cc_common.merge_cc_infos(cc_infos = [cc_info, ctx.attr.deps[0][CcInfo]])]

nocode_cc_lib = rule(
    implementation = _nocode_cc_lib_impl,
    attrs = {
        "additional_inputs": attr.label_list(allow_files = True),
        "deps": attr.label_list(),
    },
    provides = [CcInfo],
)
