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

"Repo rule used by bzlmod extension to create a repo that has a map of Python interpreters and their labels"

load(":text_util.bzl", "render")
load(":toolchains_repo.bzl", "python_toolchain_build_file_content")

def _have_same_length(*lists):
    if not lists:
        fail("expected at least one list")
    return len({len(length): None for length in lists}) == 1

_HUB_BUILD_FILE_TEMPLATE = """\
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load("@@{rules_python}//python/private:py_toolchain_suite.bzl", "py_toolchain_suite")

bzl_library(
    name = "interpreters_bzl",
    srcs = ["interpreters.bzl"],
    visibility = ["@rules_python//:__subpackages__"],
)

bzl_library(
    name = "versions_bzl",
    srcs = ["versions.bzl"],
    visibility = ["@rules_python//:__subpackages__"],
)

{toolchains}
"""

def _hub_build_file_content(
        prefixes,
        python_versions,
        set_python_version_constraints,
        user_repository_names,
        workspace_location):
    """This macro iterates over each of the lists and returns the toolchain content.

    python_toolchain_build_file_content is called to generate each of the toolchain
    definitions.
    """

    if not _have_same_length(python_versions, set_python_version_constraints, user_repository_names):
        fail("all lists must have the same length")

    # Iterate over the length of python_versions and call
    # build the toolchain content by calling python_toolchain_build_file_content
    toolchains = "\n".join(
        [
            python_toolchain_build_file_content(
                prefix = prefixes[i],
                python_version = python_versions[i],
                set_python_version_constraint = set_python_version_constraints[i],
                user_repository_name = user_repository_names[i],
            )
            for i in range(len(python_versions))
        ],
    )

    return _HUB_BUILD_FILE_TEMPLATE.format(
        toolchains = toolchains,
        rules_python = workspace_location.workspace_name,
    )

_interpreters_bzl_template = """
INTERPRETER_LABELS = {{
{interpreter_labels}
}}
DEFAULT_PYTHON_VERSION = "{default_python_version}"
"""

_line_for_hub_template = """\
    "{name}_host": Label("@{name}_host//:python"),
"""

_versions_bzl_template = """
DEFAULT_PYTHON_VERSION = "{default_python_version}"
MINOR_MAPPING = {minor_mapping}
PYTHON_VERSIONS = {python_versions}
"""

def _hub_repo_impl(rctx):
    # Create the various toolchain definitions and
    # write them to the BUILD file.
    rctx.file(
        "BUILD.bazel",
        _hub_build_file_content(
            rctx.attr.toolchain_prefixes,
            rctx.attr.toolchain_python_versions,
            rctx.attr.toolchain_set_python_version_constraints,
            rctx.attr.toolchain_user_repository_names,
            rctx.attr._rules_python_workspace,
        ),
        executable = False,
    )

    # Create a dict that is later used to create
    # a symlink to a interpreter.
    interpreter_labels = "".join([
        _line_for_hub_template.format(name = name)
        for name in rctx.attr.toolchain_user_repository_names
    ])

    rctx.file(
        "interpreters.bzl",
        _interpreters_bzl_template.format(
            # TODO @aignas 2024-09-28: before 1.0 remove the value from here
            default_python_version = rctx.attr.default_python_version,
            interpreter_labels = interpreter_labels,
        ),
        executable = False,
    )

    rctx.file(
        "versions.bzl",
        _versions_bzl_template.format(
            default_python_version = rctx.attr.default_python_version,
            minor_mapping = render.dict(rctx.attr.minor_mapping),
            python_versions = rctx.attr.python_versions or render.list(sorted({
                v: None
                for v in rctx.attr.toolchain_python_versions
            })),
        ),
        executable = False,
    )

hub_repo = repository_rule(
    doc = """\
This private rule create a repo with a BUILD file that contains a map of interpreter names
and the labels to said interpreters. This map is used to by the interpreter hub extension.
This rule also writes out the various toolchains for the different Python versions.
""",
    implementation = _hub_repo_impl,
    attrs = {
        "default_python_version": attr.string(
            doc = "Default Python version for the build in `X.Y` or `X.Y.Z` format.",
            mandatory = True,
        ),
        "minor_mapping": attr.string_dict(
            doc = "The minor mapping of the `X.Y` to `X.Y.Z` format that is used in config settings.",
            mandatory = True,
        ),
        "python_versions": attr.string_list(
            doc = "The list of python versions to include in the `interpreters.bzl` if the toolchains are not specified. Used in `WORKSPACE` builds.",
            mandatory = False,
        ),
        "toolchain_prefixes": attr.string_list(
            doc = "List prefixed for the toolchains",
            mandatory = True,
        ),
        "toolchain_python_versions": attr.string_list(
            doc = "List of Python versions for the toolchains. In `X.Y.Z` format.",
            mandatory = True,
        ),
        "toolchain_set_python_version_constraints": attr.string_list(
            doc = "List of version contraints for the toolchains",
            mandatory = True,
        ),
        "toolchain_user_repository_names": attr.string_list(
            doc = "List of the user repo names for the toolchains",
            mandatory = True,
        ),
        "_rules_python_workspace": attr.label(default = Label("//:does_not_matter_what_this_name_is")),
    },
)
