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

"""Example C++ API usage"""

load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")

def _filter_none(input_list):
    filtered_list = []
    for element in input_list:
        if element != None:
            filtered_list.append(element)
    return filtered_list

def _cc_lib_impl(ctx):
    cc_toolchain = find_cpp_toolchain(ctx)
    feature_configuration = cc_common.configure_features(
        ctx = ctx,
        cc_toolchain = cc_toolchain,
        requested_features = ctx.features,
        unsupported_features = ctx.disabled_features,
    )
    compilation_contexts = []
    linking_contexts = []
    for dep in ctx.attr.deps:
        if CcInfo in dep:
            compilation_contexts.append(dep[CcInfo].compilation_context)
            linking_contexts.append(dep[CcInfo].linking_context)

    (compilation_context, compilation_outputs) = cc_common.compile(
        name = ctx.label.name,
        actions = ctx.actions,
        feature_configuration = feature_configuration,
        cc_toolchain = cc_toolchain,
        public_hdrs = ctx.files.public_hdrs,
        private_hdrs = ctx.files.private_hdrs,
        srcs = ctx.files.srcs,
        includes = ctx.attr.includes,
        quote_includes = ctx.attr.quote_includes,
        system_includes = ctx.attr.system_includes,
        defines = ctx.attr.defines,
        user_compile_flags = ctx.attr.user_compile_flags,
        compilation_contexts = compilation_contexts,
    )
    (linking_context, linking_outputs) = cc_common.create_linking_context_from_compilation_outputs(
        name = ctx.label.name,
        actions = ctx.actions,
        feature_configuration = feature_configuration,
        cc_toolchain = cc_toolchain,
        language = "c++",
        compilation_outputs = compilation_outputs,
        linking_contexts = linking_contexts,
    )
    library = linking_outputs.library_to_link
    files = []
    files.extend(compilation_outputs.objects)
    files.extend(compilation_outputs.pic_objects)
    files.append(library.pic_static_library)
    files.append(library.static_library)

    files.append(library.dynamic_library)

    return [
        DefaultInfo(
            files = depset(_filter_none(files)),
        ),
        CcInfo(
            compilation_context = compilation_context,
            linking_context = linking_context,
        ),
    ]

cc_lib = rule(
    implementation = _cc_lib_impl,
    attrs = {
        "public_hdrs": attr.label_list(allow_files = [".h"]),
        "private_hdrs": attr.label_list(allow_files = [".h"]),
        "srcs": attr.label_list(allow_files = [".cc"]),
        "deps": attr.label_list(
            allow_empty = True,
            providers = [[CcInfo]],
        ),
        "user_compile_flags": attr.string_list(),
        "user_link_flags": attr.string_list(),
        "includes": attr.string_list(),
        "quote_includes": attr.string_list(),
        "system_includes": attr.string_list(),
        "defines": attr.string_list(),
        "alwayslink": attr.bool(default = False),
        "_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"),
    },
    fragments = ["cpp"],
)

def _cc_bin_impl(ctx):
    cc_toolchain = find_cpp_toolchain(ctx)
    feature_configuration = cc_common.configure_features(
        ctx = ctx,
        cc_toolchain = cc_toolchain,
        requested_features = ctx.features,
        unsupported_features = ctx.disabled_features,
    )
    compilation_contexts = []
    linking_contexts = []
    for dep in ctx.attr.deps:
        if CcInfo in dep:
            compilation_contexts.append(dep[CcInfo].compilation_context)
            linking_contexts.append(dep[CcInfo].linking_context)

    (_compilation_context, compilation_outputs) = cc_common.compile(
        name = ctx.label.name,
        actions = ctx.actions,
        feature_configuration = feature_configuration,
        cc_toolchain = cc_toolchain,
        srcs = ctx.files.srcs,
        compilation_contexts = compilation_contexts,
    )
    output_type = "dynamic_library" if ctx.attr.linkshared else "executable"
    user_link_flags = []
    for user_link_flag in ctx.attr.user_link_flags:
        user_link_flags.append(ctx.expand_location(user_link_flag, targets = ctx.attr.additional_linker_inputs))

    linking_outputs = cc_common.link(
        name = ctx.label.name,
        actions = ctx.actions,
        feature_configuration = feature_configuration,
        cc_toolchain = cc_toolchain,
        language = "c++",
        compilation_outputs = compilation_outputs,
        linking_contexts = linking_contexts,
        user_link_flags = user_link_flags,
        link_deps_statically = ctx.attr.linkstatic,
        additional_inputs = ctx.files.additional_linker_inputs,
        output_type = output_type,
    )
    files = []
    if output_type == "executable":
        files.append(linking_outputs.executable)
    elif output_type == "dynamic_library":
        files.append(linking_outputs.library_to_link.dynamic_library)
        files.append(linking_outputs.library_to_link.resolved_symlink_dynamic_library)

    return [
        DefaultInfo(
            files = depset(_filter_none(files)),
            runfiles = ctx.runfiles(files = ctx.files.data),
        ),
    ]

cc_bin = rule(
    implementation = _cc_bin_impl,
    attrs = {
        "srcs": attr.label_list(allow_files = [".cc"]),
        "additional_linker_inputs": attr.label_list(
            allow_empty = True,
            allow_files = [".lds"],
        ),
        "deps": attr.label_list(
            allow_empty = True,
            providers = [CcInfo],
        ),
        "data": attr.label_list(
            default = [],
            allow_files = True,
        ),
        "user_link_flags": attr.string_list(),
        "linkstatic": attr.bool(default = True),
        "linkshared": attr.bool(default = False),
        "_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"),
    },
    fragments = ["cpp"],
)
