# Copyright 2016 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.
"""Rules for configuring the C++ toolchain (experimental)."""

load("@bazel_tools//tools/cpp:windows_cc_configure.bzl", "configure_windows_toolchain")
load("@bazel_tools//tools/cpp:osx_cc_configure.bzl", "configure_osx_toolchain")
load("@bazel_tools//tools/cpp:unix_cc_configure.bzl", "configure_unix_toolchain")
load(
    "@bazel_tools//tools/cpp:lib_cc_configure.bzl",
    "get_cpu_value",
    "resolve_labels",
)
load("@bazel_tools//tools/osx:xcode_configure.bzl", "run_xcode_locator")

def _generate_cpp_only_build_file(repository_ctx, cpu_value, paths):
    repository_ctx.template(
        "BUILD",
        paths["@bazel_tools//tools/cpp:BUILD.toolchains.tpl"],
        {"%{name}": cpu_value},
    )

def cc_autoconf_toolchains_impl(repository_ctx):
    """Generate BUILD file with 'toolchain' targets for the local host C++ toolchain.

    Args:
      repository_ctx: repository context
    """
    paths = resolve_labels(repository_ctx, [
        "@bazel_tools//tools/cpp:BUILD.toolchains.tpl",
        "@bazel_tools//tools/osx/crosstool:BUILD.toolchains",
        "@bazel_tools//tools/osx:xcode_locator.m",
    ])
    env = repository_ctx.os.environ
    cpu_value = get_cpu_value(repository_ctx)

    # Should we try to find C++ toolchain at all? If not, we don't have to generate toolchains for C++ at all.
    should_detect_cpp_toolchain = "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN" not in env or env["BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN"] != "1"

    # Should we unconditionally *not* use xcode? If so, we don't have to run Xcode locator ever.
    should_use_cpp_only_toolchain = "BAZEL_USE_CPP_ONLY_TOOLCHAIN" in env and env["BAZEL_USE_CPP_ONLY_TOOLCHAIN"] == "1"

    # Should we unconditionally use xcode? If so, we don't have to run Xcode locator now.
    should_use_xcode = "BAZEL_USE_XCODE_TOOLCHAIN" in env and env["BAZEL_USE_XCODE_TOOLCHAIN"] == "1"

    if not should_detect_cpp_toolchain:
        repository_ctx.file("BUILD", "# C++ toolchain autoconfiguration was disabled by BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN env variable.")
    elif cpu_value.startswith("darwin") and not should_use_cpp_only_toolchain:
        xcode_toolchains = []

        # Only detect xcode if the user didn't tell us it will be there.
        if not should_use_xcode:
            # TODO(#6926): Unify C++ and ObjC toolchains so we don't have to run xcode locator to generate toolchain targets.
            # And also so we don't have to keep this code in sync with //tools/cpp:osx_cc_configure.bzl.
            (xcode_toolchains, _xcodeloc_err) = run_xcode_locator(
                repository_ctx,
                paths["@bazel_tools//tools/osx:xcode_locator.m"],
            )

        if should_use_xcode or xcode_toolchains:
            repository_ctx.symlink(paths["@bazel_tools//tools/osx/crosstool:BUILD.toolchains"], "BUILD")
        else:
            _generate_cpp_only_build_file(repository_ctx, cpu_value, paths)
    else:
        _generate_cpp_only_build_file(repository_ctx, cpu_value, paths)

cc_autoconf_toolchains = repository_rule(
    environ = [
        "BAZEL_USE_CPP_ONLY_TOOLCHAIN",
        "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN",
    ],
    implementation = cc_autoconf_toolchains_impl,
    configure = True,
)

def cc_autoconf_impl(repository_ctx, overriden_tools = dict()):
    """Generate BUILD file with 'cc_toolchain' targets for the local host C++ toolchain.

    Args:
       repository_ctx: repository context
       overriden_tools: dict of tool paths to use instead of autoconfigured tools
    """

    env = repository_ctx.os.environ
    cpu_value = get_cpu_value(repository_ctx)
    if "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN" in env and env["BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN"] == "1":
        paths = resolve_labels(repository_ctx, [
            "@bazel_tools//tools/cpp:BUILD.empty.tpl",
            "@bazel_tools//tools/cpp:empty_cc_toolchain_config.bzl",
        ])
        repository_ctx.symlink(paths["@bazel_tools//tools/cpp:empty_cc_toolchain_config.bzl"], "cc_toolchain_config.bzl")
        repository_ctx.template("BUILD", paths["@bazel_tools//tools/cpp:BUILD.empty.tpl"], {
            "%{cpu}": get_cpu_value(repository_ctx),
        })
    elif cpu_value == "freebsd" or cpu_value == "openbsd":
        paths = resolve_labels(repository_ctx, [
            "@bazel_tools//tools/cpp:BUILD.static.bsd",
            "@bazel_tools//tools/cpp:bsd_cc_toolchain_config.bzl",
        ])

        # This is defaulting to a static crosstool. We should eventually
        # autoconfigure this platform too. Theorically, FreeBSD and OpenBSD
        # should be straightforward to add but we cannot run them in a Docker
        # container so skipping until we have proper tests for these platforms.
        repository_ctx.symlink(paths["@bazel_tools//tools/cpp:bsd_cc_toolchain_config.bzl"], "cc_toolchain_config.bzl")
        repository_ctx.symlink(paths["@bazel_tools//tools/cpp:BUILD.static.bsd"], "BUILD")
    elif cpu_value in ["x64_windows", "arm64_windows"]:
        # TODO(ibiryukov): overriden_tools are only supported in configure_unix_toolchain.
        # We might want to add that to Windows too(at least for msys toolchain).
        configure_windows_toolchain(repository_ctx)
    elif (cpu_value.startswith("darwin") and
          ("BAZEL_USE_CPP_ONLY_TOOLCHAIN" not in env or env["BAZEL_USE_CPP_ONLY_TOOLCHAIN"] != "1")):
        configure_osx_toolchain(repository_ctx, cpu_value, overriden_tools)
    else:
        configure_unix_toolchain(repository_ctx, cpu_value, overriden_tools)

MSVC_ENVVARS = [
    "BAZEL_VC",
    "BAZEL_VC_FULL_VERSION",
    "BAZEL_VS",
    "BAZEL_WINSDK_FULL_VERSION",
    "VS90COMNTOOLS",
    "VS100COMNTOOLS",
    "VS110COMNTOOLS",
    "VS120COMNTOOLS",
    "VS140COMNTOOLS",
    "VS150COMNTOOLS",
    "VS160COMNTOOLS",
    "TMP",
    "TEMP",
]

cc_autoconf = repository_rule(
    environ = [
        "ABI_LIBC_VERSION",
        "ABI_VERSION",
        "BAZEL_COMPILER",
        "BAZEL_HOST_SYSTEM",
        "BAZEL_CXXOPTS",
        "BAZEL_LINKOPTS",
        "BAZEL_LINKLIBS",
        "BAZEL_LLVM_COV",
        "BAZEL_LLVM_PROFDATA",
        "BAZEL_PYTHON",
        "BAZEL_SH",
        "BAZEL_TARGET_CPU",
        "BAZEL_TARGET_LIBC",
        "BAZEL_TARGET_SYSTEM",
        "BAZEL_USE_CPP_ONLY_TOOLCHAIN",
        "BAZEL_USE_XCODE_TOOLCHAIN",
        "BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN",
        "BAZEL_USE_LLVM_NATIVE_COVERAGE",
        "BAZEL_LLVM",
        "BAZEL_IGNORE_SYSTEM_HEADERS_VERSIONS",
        "USE_CLANG_CL",
        "CC",
        "CC_CONFIGURE_DEBUG",
        "CC_TOOLCHAIN_NAME",
        "CPLUS_INCLUDE_PATH",
        "DEVELOPER_DIR",
        "GCOV",
        "HOMEBREW_RUBY_PATH",
        "SYSTEMROOT",
        "USER",
    ] + MSVC_ENVVARS,
    implementation = cc_autoconf_impl,
    configure = True,
)

def cc_configure():
    """A C++ configuration rules that generate the crosstool file."""
    cc_autoconf_toolchains(name = "local_config_cc_toolchains")
    cc_autoconf(name = "local_config_cc")
    native.bind(name = "cc_toolchain", actual = "@local_config_cc//:toolchain")
    native.register_toolchains(
        # Use register_toolchain's target pattern expansion to register all toolchains in the package.
        "@local_config_cc_toolchains//:all",
    )

def _cc_configure_extension_impl(ctx):
    cc_autoconf_toolchains(name = "local_config_cc_toolchains")
    cc_autoconf(name = "local_config_cc")

cc_configure_extension = module_extension(implementation = _cc_configure_extension_impl)
