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

"""A helper for creating CcToolchainProvider."""

load(":common/cc/cc_common.bzl", "cc_common")
load(":common/cc/cc_helper.bzl", "cc_helper")
load(":common/cc/cc_info.bzl", "CcInfo")
load(":common/cc/cc_toolchain_info.bzl", "CcToolchainInfo")
load(":common/objc/objc_common.bzl", "objc_common")
load(":common/paths.bzl", "paths")

cc_internal = _builtins.internal.cc_internal

_TOOL_PATH_ONLY_TOOLS = [
    "gcov-tool",
    "gcov",
    "llvm-profdata",
    "llvm-cov",
]

_REQUIRED_TOOLS = [
    "ar",
    "cpp",
    "gcc",
    "ld",
    "nm",
    "objdump",
    "strip",
]

_SYSROOT_START = "%sysroot%/"
_WORKSPACE_START = "%workspace%/"
_CROSSTOOL_START = "%crosstool_top%/"
_PACKAGE_START = "%package("
_PACKAGE_END = ")%"
_BUILTIN_INCLUDE_FILE_SUFFIX = "include/stdc-predef.h"

def _builtin_includes(libc):
    result = []
    for artifact in libc.to_list():
        if artifact.path.endswith(_BUILTIN_INCLUDE_FILE_SUFFIX):
            result.append(artifact)
    return result

def _legacy_cc_flags_make_variable(toolchain_make_vars):
    legacy_cc_flags = ""
    for variable in toolchain_make_vars:
        if variable[0] == "CC_FLAGS":
            legacy_cc_flags = variable[1]
    return legacy_cc_flags

def _additional_make_variables(toolchain_make_vars):
    make_vars = {}

    # The following are to be used to allow some build rules to avoid the limits on stack frame
    # sizes and variable-length arrays.
    # These variables are initialized here, but may be overridden by the getMakeVariables() checks.
    make_vars["STACK_FRAME_UNLIMITED"] = ""
    for variable in toolchain_make_vars:
        make_vars[variable[0]] = variable[1]
    make_vars.pop("CC_FLAGS", None)
    return make_vars

def _compute_tool_paths(toolchain_config_info, crosstool_top_path):
    tool_paths_collector = {}
    for tool in toolchain_config_info.tool_paths():
        path_str = tool[1]
        if not paths.is_normalized(path_str):
            fail("The include path '" + path_str + "' is not normalized.")
        tool_paths_collector[tool[0]] = paths.get_relative(crosstool_top_path, path_str)

    # These tools can only be declared using tool paths, so action-only toolchains should still
    # be allowed to declared them while still being treated as an action-only toolchain. If a tool
    # that can be specified with actions is declared using paths, the toolchain will be treated as
    # a tool-path toolchain to enforce users to migrate their toolchain fully.
    contains_all = True
    for key in tool_paths_collector.keys():
        if key not in _TOOL_PATH_ONLY_TOOLS:
            contains_all = False
            break
    if contains_all:
        for tool in _REQUIRED_TOOLS:
            tool_paths_collector[tool] = paths.get_relative(crosstool_top_path, tool)
    else:
        for tool in _REQUIRED_TOOLS:
            if tool not in tool_paths_collector.keys():
                fail("Tool path for '" + tool + "' is missing")
    return tool_paths_collector

def _resolve_include_dir(target_label, s, sysroot, crosstool_path):
    """ Resolve the given include directory.

    If it starts with %sysroot%/, that part is replaced with the actual sysroot.

    If it starts with %workspace%/, that part is replaced with the empty string (essentially
    making it relative to the build directory).

    If it starts with %crosstool_top%/ or is any relative path, it is interpreted relative to
    the crosstool top. The use of assumed-crosstool-relative specifications is considered
    deprecated, and all such uses should eventually be replaced by "%crosstool_top%/".

    If it is of the form %package(@repository//my/package)%/folder, then it is interpreted as
    the named folder in the appropriate package. All of the normal package syntax is supported. The
    /folder part is optional.

    It is illegal if it starts with a % and does not match any of the above forms to avoid
    accidentally silently ignoring misspelled prefixes.

    If it is absolute, it remains unchanged.
    """
    package_end_index = s.find(_PACKAGE_END)
    if package_end_index != -1 and s.startswith(_PACKAGE_START):
        package = s[len(_PACKAGE_START):package_end_index]
        if package.find(":") >= 0:
            fail("invalid package identifier '" + package + "': contains ':'")

        # This is necessary to avoid the hard work of parsing,
        # and use an already existing API.
        dummy_label = target_label.relative(package + ":dummy_target")
        repo_prefix = dummy_label.workspace_root
        path_prefix = paths.get_relative(repo_prefix, dummy_label.package)
        path_start_index = package_end_index + len(_PACKAGE_END)
        if path_start_index + 1 < len(s):
            if s[path_start_index] != "/":
                fail("The path in the package for '" + s + "' is not valid")
            path_string = s[path_start_index + 1:]
        else:
            path_string = ""
    elif s.startswith(_SYSROOT_START):
        if sysroot == None:
            fail("A %sysroot% prefix is only allowed if the default_sysroot option is set")
        path_prefix = sysroot
        path_string = s[len(_SYSROOT_START):len(s)]
    elif s.startswith(_WORKSPACE_START):
        path_prefix = ""
        path_string = s[len(_WORKSPACE_START):len(s)]
    else:
        path_prefix = crosstool_path
        if s.startswith(_CROSSTOOL_START):
            path_string = s[len(_CROSSTOOL_START):len(s)]
        elif s.startswith("%"):
            fail("The include path '" + s + "' has an " + "unrecognized %prefix%")
        else:
            path_string = s

    return paths.get_relative(path_prefix, path_string)

def get_cc_toolchain_provider(ctx, attributes, xcode_config_info):
    """Constructs a CcToolchainProvider instance.

    Args:
        ctx: rule context.
        attributes: encapsulated attributes of cc_toolchain rule.
        xcode_config_info: XcodeConfigInfo provider can be none if not present.
    Returns:
        A constructed CcToolchainProvider instance.
    """
    toolchain_config_info = attributes.cc_toolchain_config_info
    tools_directory = cc_helper.package_exec_path(
        ctx,
        attributes.cc_toolchain_label.package,
        ctx.configuration.is_sibling_repository_layout(),
    )
    tool_paths = _compute_tool_paths(toolchain_config_info, tools_directory)
    toolchain_features = cc_internal.cc_toolchain_features(toolchain_config_info = toolchain_config_info, tools_directory = tools_directory)
    fdo_context = cc_internal.fdo_context(
        ctx = ctx,
        configuration = ctx.configuration,
        cpp_config = ctx.fragments.cpp,
        tool_paths = tool_paths,
        fdo_prefetch_provider = attributes.fdo_prefetch_provider,
        propeller_optimize_provider = attributes.propeller_optimize_provider,
        mem_prof_profile_provider = attributes.mem_prof_profile_provider,
        fdo_optimize_provider = attributes.fdo_optimize_provider,
        fdo_profile_provider = attributes.fdo_profile_provider,
        x_fdo_profile_provider = attributes.x_fdo_profile_provider,
        cs_fdo_profile_provider = attributes.cs_fdo_profile_provider,
        all_files = attributes.all_files,
        zipper = attributes.zipper,
        cc_toolchain_config_info = attributes.cc_toolchain_config_info,
        fdo_optimize_artifacts = attributes.fdo_optimize_artifacts,
        fdo_optimize_label = attributes.fdo_optimize_label,
    )
    if fdo_context == None:
        return None
    runtime_solib_dir_base = attributes.runtime_solib_dir_base
    runtime_solib_dir = paths.get_relative(ctx.bin_dir.path, runtime_solib_dir_base)
    solib_directory = "_solib_" + toolchain_config_info.target_cpu()
    default_sysroot = None
    if toolchain_config_info.builtin_sysroot() != "":
        default_sysroot = toolchain_config_info.builtin_sysroot()
    if attributes.libc_top_label == None:
        sysroot = default_sysroot
    else:
        sysroot = attributes.libc_top_label.package

    static_runtime_lib = attributes.static_runtime_lib
    if static_runtime_lib != None:
        static_runtime_link_inputs = static_runtime_lib[DefaultInfo].files
    else:
        static_runtime_link_inputs = None

    dynamic_runtime_lib = attributes.dynamic_runtime_lib
    if dynamic_runtime_lib != None:
        dynamic_runtime_link_symlinks_elems = []
        for artifact in dynamic_runtime_lib[DefaultInfo].files.to_list():
            if cc_helper.is_valid_shared_library_artifact(artifact):
                dynamic_runtime_link_symlinks_elems.append(cc_internal.solib_symlink_action(
                    ctx = ctx,
                    artifact = artifact,
                    solib_directory = solib_directory,
                    runtime_solib_dir_base = runtime_solib_dir_base,
                ))
        if len(dynamic_runtime_link_symlinks_elems) == 0:
            dynamic_runtime_link_symlinks = depset()
        else:
            dynamic_runtime_link_symlinks = depset(direct = dynamic_runtime_link_symlinks_elems)
    else:
        dynamic_runtime_link_symlinks = None

    module_map = None
    if attributes.module_map != None and attributes.module_map_artifact != None:
        module_map = cc_common.create_module_map(file = attributes.module_map_artifact, name = "crosstool")

    cc_compilation_context = cc_common.create_compilation_context(module_map = module_map)

    builtin_include_directories = []
    for s in toolchain_config_info.cxx_builtin_include_directories():
        builtin_include_directories.append(_resolve_include_dir(ctx.label, s, sysroot, tools_directory))

    if xcode_config_info:
        build_vars = objc_common.apple_cc_toolchain_build_variables(
            xcode_config_info,
            ctx.fragments.apple.single_arch_platform,
            ctx.fragments.apple.cpu(),
            ctx.fragments.cpp,
            sysroot,
        )
    else:
        build_vars = cc_internal.cc_toolchain_variables(vars = objc_common.get_common_vars(ctx.fragments.cpp, sysroot))

    return CcToolchainInfo(
        cpp_configuration = ctx.fragments.cpp,
        toolchain_config_info = toolchain_config_info,
        toolchain_features = toolchain_features,
        crosstool_top_path = tools_directory,
        static_runtime_lib_depset = static_runtime_link_inputs,
        dynamic_runtime_lib_depset = dynamic_runtime_link_symlinks,
        dynamic_runtime_solib_dir = runtime_solib_dir,
        cc_info = CcInfo(
            compilation_context = cc_compilation_context,
        ),
        builtin_include_files = _builtin_includes(attributes.libc),
        built_in_include_directories = builtin_include_directories,
        sysroot = sysroot,
        fdo_context = fdo_context,
        is_tool_configuration = ctx.configuration.is_tool_configuration(),
        tool_paths = tool_paths,
        default_sysroot = default_sysroot,
        # The runtime sysroot should really be set from --grte_top. However, currently libc has
        # no way to set the sysroot. The CROSSTOOL file does set the runtime sysroot, in the
        # builtin_sysroot field. This implies that you can not arbitrarily mix and match
        # Crosstool and libc versions, you must always choose compatible ones.
        runtime_sysroot = default_sysroot,
        solib_dir = solib_directory,
        additional_make_variables = _additional_make_variables(toolchain_config_info.make_variables()),
        legacy_cc_flags_make_variable = _legacy_cc_flags_make_variable(toolchain_config_info.make_variables()),
        objcopy_executable = tool_paths.get("objcopy", ""),
        compiler_executable = tool_paths.get("gcc", ""),
        preprocessor_executable = tool_paths.get("cpp", ""),
        nm_executable = tool_paths.get("nm", ""),
        objdump_executable = tool_paths.get("objdump", ""),
        ar_executable = tool_paths.get("ar", ""),
        strip_executable = tool_paths.get("strip", ""),
        ld_executable = tool_paths.get("ld", ""),
        gcov_executable = tool_paths.get("gcov", ""),
        build_variables = build_vars,
        xcode_config_info = xcode_config_info,
        all_files = attributes.all_files,
        all_files_including_libc = attributes.all_files_including_libc,
        compiler_files = attributes.compiler_files,
        compiler_files_without_includes = attributes.compiler_files_without_includes,
        strip_files = attributes.strip_files,
        objcopy_files = attributes.objcopy_files,
        as_files = attributes.as_files,
        ar_files = attributes.ar_files,
        linker_files = attributes.linker_files,
        if_so_builder = attributes.if_so_builder,
        dwp_files = attributes.dwp_files,
        coverage_files = attributes.coverage_files,
        supports_param_files = attributes.supports_param_files,
        supports_header_parsing = attributes.supports_header_parsing,
        link_dynamic_library_tool = attributes.link_dynamic_library_tool,
        grep_includes = attributes.grep_includes,
        allowlist_for_layering_check = attributes.allowlist_for_layering_check,
        build_info_files = attributes.build_info_files,
        toolchain_label = ctx.label,
    )
