# 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_helper.bzl", "cc_helper")
load(":common/paths.bzl", "paths")
load(":common/cc/cc_common.bzl", "cc_common")

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):
    """Constructs a CcToolchainProvider instance.

    Args:
        ctx: rule context.
        attributes: an instance of CcToolchainAttributesProvider.
    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,
        attributes = attributes,
        configuration = ctx.configuration,
        cpp_config = ctx.fragments.cpp,
        tool_paths = tool_paths,
    )
    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

    if attributes.target_libc_top_label() == None:
        target_sysroot = sysroot
    else:
        target_sysroot = attributes.target_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))

    return cc_internal.construct_toolchain_provider(
        ctx = ctx,
        cpp_config = ctx.fragments.cpp,
        toolchain_features = toolchain_features,
        tools_directory = tools_directory,
        attributes = attributes,
        static_runtime_link_inputs = static_runtime_link_inputs,
        dynamic_runtime_link_symlinks = dynamic_runtime_link_symlinks,
        runtime_solib_dir = runtime_solib_dir,
        cc_compilation_context = cc_compilation_context,
        builtin_include_files = _builtin_includes(attributes.libc()),
        target_builtin_include_files = _builtin_includes(attributes.target_libc()),
        builtin_include_directories = builtin_include_directories,
        sysroot = sysroot,
        target_sysroot = target_sysroot,
        fdo_context = fdo_context,
        is_tool_configuration = ctx.configuration.is_tool_configuration(),
        tool_paths = tool_paths,
        toolchain_config_info = toolchain_config_info,
        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_directory = 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 = tool_paths.get("objcopy", ""),
        compiler = tool_paths.get("gcc", ""),
        preprocessor = tool_paths.get("cpp", ""),
        nm = tool_paths.get("nm", ""),
        objdump = tool_paths.get("objdump", ""),
        ar = tool_paths.get("ar", ""),
        strip = tool_paths.get("strip", ""),
        ld = tool_paths.get("ld", ""),
        gcov = tool_paths.get("gcov", ""),
    )
