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

# LOCAL MODIFICATIONS
# this has a PR patched in on top of the original
# https://github.com/bazelbuild/bazel-skylib/blob/7b859037a673db6f606661323e74c5d4751595e6/rules/private/copy_file_private.bzl
# https://github.com/bazelbuild/bazel-skylib/pull/324

"""Implementation of copy_file macro and underlying rules.

These rules copy a file to another location using Bash (on Linux/macOS) or
cmd.exe (on Windows). `_copy_xfile` marks the resulting file executable,
`_copy_file` does not.
"""

load(":copy_common.bzl", _COPY_EXECUTION_REQUIREMENTS = "COPY_EXECUTION_REQUIREMENTS", _progress_path = "progress_path")
load(":directory_path.bzl", "DirectoryPathInfo")

_COREUTILS_TOOLCHAIN = "@aspect_bazel_lib//lib:coreutils_toolchain_type"

# Declare toolchains used by copy file actions so that downstream rulesets can pass it into
# the `toolchains` attribute of their rule.
COPY_FILE_TOOLCHAINS = [
    _COREUTILS_TOOLCHAIN,
]

def copy_file_action(ctx, src, dst, dir_path = None):
    """Factory function that creates an action to copy a file from src to dst.

    If src is a TreeArtifact, dir_path must be specified as the path within
    the TreeArtifact to the file to copy.

    This helper is used by copy_file. It is exposed as a public API so it can be used within
    other rule implementations.

    To use `copy_file_action` in your own rules, you need to include the toolchains it uses
    in your rule definition. For example:

    ```starlark
    load("@aspect_bazel_lib//lib:copy_file.bzl", "COPY_FILE_TOOLCHAINS")

    my_rule = rule(
        ...,
        toolchains = COPY_FILE_TOOLCHAINS,
    )
    ```

    Additionally, you must ensure that the coreutils toolchain is has been registered in your
    WORKSPACE if you are not using bzlmod:

    ```starlark
    load("@aspect_bazel_lib//lib:repositories.bzl", "register_coreutils_toolchains")

    register_coreutils_toolchains()
    ```

    Args:
        ctx: The rule context.
        src: The source file to copy or TreeArtifact to copy a single file out of.
        dst: The destination file.
        dir_path: If src is a TreeArtifact, the path within the TreeArtifact to the file to copy.
    """

    if dst.is_directory:
        fail("dst must not be a TreeArtifact")
    if src.is_directory:
        if not dir_path:
            fail("dir_path must be set if src is a TreeArtifact")
        src_path = "/".join([src.path, dir_path])
    else:
        src_path = src.path

    coreutils = ctx.toolchains[_COREUTILS_TOOLCHAIN].coreutils_info

    ctx.actions.run(
        executable = coreutils.bin,
        arguments = ["cp", src_path, dst.path],
        inputs = [src],
        outputs = [dst],
        mnemonic = "CopyFile",
        progress_message = "Copying file %s" % _progress_path(src),
        execution_requirements = _COPY_EXECUTION_REQUIREMENTS,
    )

def _copy_file_impl(ctx):
    if ctx.attr.allow_symlink:
        if len(ctx.files.src) != 1:
            fail("src must be a single file when allow_symlink is True")
        if ctx.files.src[0].is_directory:
            fail("cannot use copy_file to create a symlink to a directory")
        ctx.actions.symlink(
            output = ctx.outputs.out,
            target_file = ctx.files.src[0],
            is_executable = ctx.attr.is_executable,
        )
    elif DirectoryPathInfo in ctx.attr.src:
        copy_file_action(
            ctx,
            ctx.attr.src[DirectoryPathInfo].directory,
            ctx.outputs.out,
            dir_path = ctx.attr.src[DirectoryPathInfo].path,
        )
    else:
        if len(ctx.files.src) != 1:
            fail("src must be a single file or a target that provides a DirectoryPathInfo")
        if ctx.files.src[0].is_directory:
            fail("cannot use copy_file on a directory; try copy_directory instead")
        copy_file_action(ctx, ctx.files.src[0], ctx.outputs.out)

    files = depset(direct = [ctx.outputs.out])
    runfiles = ctx.runfiles(files = [ctx.outputs.out])
    if ctx.attr.is_executable:
        return [DefaultInfo(files = files, runfiles = runfiles, executable = ctx.outputs.out)]
    else:
        return [DefaultInfo(files = files, runfiles = runfiles)]

_ATTRS = {
    "src": attr.label(mandatory = True, allow_files = True),
    "is_executable": attr.bool(mandatory = True),
    "allow_symlink": attr.bool(mandatory = True),
    "out": attr.output(mandatory = True),
}

_copy_file = rule(
    implementation = _copy_file_impl,
    provides = [DefaultInfo],
    attrs = _ATTRS,
    toolchains = COPY_FILE_TOOLCHAINS,
)

_copy_xfile = rule(
    implementation = _copy_file_impl,
    executable = True,
    provides = [DefaultInfo],
    attrs = _ATTRS,
    toolchains = COPY_FILE_TOOLCHAINS,
)

def copy_file(name, src, out, is_executable = False, allow_symlink = False, **kwargs):
    """Copies a file or directory to another location.

    `native.genrule()` is sometimes used to copy files (often wishing to rename them). The 'copy_file' rule does this with a simpler interface than genrule.

    This rule uses a Bash command on Linux/macOS/non-Windows, and a cmd.exe command on Windows (no Bash is required).

    If using this rule with source directories, it is recommended that you use the
    `--host_jvm_args=-DBAZEL_TRACK_SOURCE_DIRECTORIES=1` startup option so that changes
    to files within source directories are detected. See
    https://github.com/bazelbuild/bazel/commit/c64421bc35214f0414e4f4226cc953e8c55fa0d2
    for more context.

    Args:
      name: Name of the rule.
      src: A Label. The file to make a copy of.
          (Can also be the label of a rule that generates a file.)
      out: Path of the output file, relative to this package.
      is_executable: A boolean. Whether to make the output file executable. When
          True, the rule's output can be executed using `bazel run` and can be
          in the srcs of binary and test rules that require executable sources.
          WARNING: If `allow_symlink` is True, `src` must also be executable.
      allow_symlink: A boolean. Whether to allow symlinking instead of copying.
          When False, the output is always a hard copy. When True, the output
          *can* be a symlink, but there is no guarantee that a symlink is
          created (i.e., at the time of writing, we don't create symlinks on
          Windows). Set this to True if you need fast copying and your tools can
          handle symlinks (which most UNIX tools can).
      **kwargs: further keyword arguments, e.g. `visibility`
    """

    copy_file_impl = _copy_file
    if is_executable:
        copy_file_impl = _copy_xfile

    copy_file_impl(
        name = name,
        src = src,
        out = out,
        is_executable = is_executable,
        allow_symlink = allow_symlink,
        **kwargs
    )
