"""This module defines the cipd_install repository rule.

The cipd_install repository rule hermetically installs a CIPD package as an external Bazel
repository.

Files in the CIPD package can be added as dependencies to other Bazel targets in two ways: either
individually via a label such as "@my_cipd_pkg//:path/to/file", or by adding
"@my_cipd_pkg//:all_files" as a dependency, which is a filegroup that includes the entire contents
of the CIPD package. The contents of the generated BUILD.bazel file which facilitates this are
configurable, e.g. multiple smaller packages.

Note: Any files with spaces in their names cannot be used by Bazel and are thus excluded
from the generated Bazel rules.

If a Bazel target adds a CIPD package as a dependency, its contents will appear under the runfiles
directory. Example:

```
# WORKSPACE
cipd_install(
    name = "git_linux",
    package = "infra/3pp/tools/git/linux-amd64",
    version = "version:2.29.2.chromium.6",
)

# BUILD.bazel
go_library(
    name = "git_util.go",
    srcs = ["git_util.go"],
    data = ["@git_linux//:all_files"],
    ...
)

# git_util.go
import (
    "path/filepath"

    "go.skia.org/infra/bazel/go/bazel"
)

func FindGitBinary() string {
    return filepath.Join(bazel.RunfilesDir(), "external/git_linux/bin/git")
}
```

For Bazel targets that must support multiple operating systems, one can declare OS-specific CIPD
packages in the WORKSPACE file, and select the correct package according to the host OS via a
select[1] statement. Example:

```
# WORKSPACE
cipd_install(
    name = "git_linux",
    package = "infra/3pp/tools/git/linux-amd64",
    version = "version:2.29.2.chromium.6",
)
cipd_install(
    name = "git_win",
    package = "infra/3pp/tools/git/windows-amd64",
    version = "version:2.29.2.chromium.6",
)

# BUILD.bazel
go_library(
    name = "git_util.go",
    srcs = ["git_util.go"],
    data = select({
        "@platforms//os:linux": ["@git_linux//:all_files"],
        "@platforms//os:windows": ["@git_win//:all_files"],
    }),
    ...
)
```

As an alternative, we could extract any such select statements as Bazel macros, which would keep
BUILD files short. Example:

```
# cipd_packages.bzl
def git():
    return select({
        "@platforms//os:linux": ["@git_linux//:all_files"],
        "@platforms//os:windows": ["@git_win//:all_files"],
    })

# BUILD.bazel
load(":cipd_packages.bzl", "git")

go_library(
    name = "git_util.go",
    srcs = ["git_util.go"],
    data = git(),
    ...
)
```

Note that runfile generation is disabled on Windows by default, and must be enabled with
--enable_runfiles[2] for the above mechanism to work.

[1] https://bazel.build/docs/configurable-attributes
[2] https://bazel.build/reference/command-line-reference#flag--enable_runfiles
"""

load(":common.bzl", "fail_if_nonzero_status")

def _postinstall_script(repository_ctx, script_name, script_content):
    repository_ctx.report_progress("Executing postinstall script...")
    repository_ctx.file(
        script_name,
        content = script_content,
        executable = True,
    )
    exec_result = repository_ctx.execute(
        [repository_ctx.path(script_name)],
        quiet = repository_ctx.attr.quiet,
    )
    fail_if_nonzero_status(exec_result, "Failed to run postinstall script.")
    repository_ctx.delete(repository_ctx.path(script_name))

_DEFAULT_BUILD_FILE_CONTENT = """
# To add a specific file inside this CIPD package as a dependency, use a label such as
# @my_cipd_pkg//:path/to/file.
# The exclude pattern prevents files with spaces in their names from tripping up Bazel.
exports_files(glob(include=["**/*"], exclude=["**/* *"]))

# Convenience filegroup to add all files in this CIPD package as dependencies.
filegroup(
    name = "all_files",
    # The exclude pattern prevents files with spaces in their names from tripping up Bazel.
    srcs = glob(include=["**/*"], exclude=["**/* *"]),
    visibility = ["//visibility:public"],
)
"""

def _cipd_install_impl(repository_ctx):
    is_windows = "windows" in repository_ctx.os.name.lower()
    is_posix = not is_windows  # This is a safe assumption given our fleet of test machines.

    # Install the CIPD package.
    cipd_client = Label("@depot_tools//:cipd.bat" if is_windows else "@depot_tools//:cipd")
    repository_ctx.report_progress("Installing CIPD package...")
    exec_result = repository_ctx.execute(
        [
            repository_ctx.path(cipd_client),
            "install",
            repository_ctx.attr.package,
            repository_ctx.attr.version,
            "-root",
            ".",
        ],
        quiet = repository_ctx.attr.quiet,
    )
    fail_if_nonzero_status(exec_result, "Failed to fetch CIPD package.")

    # Generate BUILD.bazel file.
    build_file_content = repository_ctx.attr.build_file_content
    if not build_file_content:
        build_file_content = _DEFAULT_BUILD_FILE_CONTENT
    repository_ctx.file("BUILD.bazel", content = build_file_content)

    # Optionally run the postinstall script if one was given.
    if is_posix and repository_ctx.attr.postinstall_script_posix != "":
        _postinstall_script(
            repository_ctx,
            "postinstall.sh",
            repository_ctx.attr.postinstall_script_posix,
        )
    if is_windows and repository_ctx.attr.postinstall_script_win != "":
        _postinstall_script(
            repository_ctx,
            # The .bat extension is needed under Windows, or the OS won't execute the script.
            "postinstall.bat",
            repository_ctx.attr.postinstall_script_win,
        )

cipd_install = repository_rule(
    implementation = _cipd_install_impl,
    attrs = {
        "package": attr.string(
            doc = """CIPD package name, e.g. "infra/3pp/tools/git/linux-amd64".""",
            mandatory = True,
        ),
        "version": attr.string(
            doc = """CIPD package version, e.g. "version:2.29.2.chromium.6".""",
            mandatory = True,
        ),
        "build_file_content": attr.string(
            doc = """If set, will be used as the content of the BUILD.bazel file. Otherwise, a
default BUILD.bazel file will be created with an all_files target.""",
        ),
        "postinstall_script_posix": attr.string(
            doc = """Contents of post-install script to execute. Ignored if Bazel is running on a
non-POSIX OS. Optional.""",
        ),
        "postinstall_script_win": attr.string(
            doc = """Contents of post-install script to execute. Ignored if Bazel is not running on
Windows. Optional.""",
        ),
        "quiet": attr.bool(
            default = True,
            doc = "Whether stdout and stderr should be printed to the terminal for debugging.",
        ),
    },
    doc = "Hermetically installs a CIPD package as an external Bazel repository.",
)
