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

"""A test rule that compares two binary files or two directories.

Similar to `bazel-skylib`'s [`diff_test`](https://github.com/bazelbuild/bazel-skylib/blob/main/rules/diff_test.bzl)
but also supports comparing directories.

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

load("//lib:utils.bzl", "default_timeout")
load(":directory_path.bzl", "DirectoryPathInfo")

def _runfiles_path(f):
    if f.root.path:
        return f.path[len(f.root.path) + 1:]  # generated file
    else:
        return f.path  # source file

def _diff_test_impl(ctx):
    is_windows = ctx.target_platform_has_constraint(ctx.attr._windows_constraint[platform_common.ConstraintValueInfo])

    if DirectoryPathInfo in ctx.attr.file1:
        file1 = ctx.attr.file1[DirectoryPathInfo].directory
        file1_path = "/".join([_runfiles_path(file1), ctx.attr.file1[DirectoryPathInfo].path])
    else:
        if len(ctx.files.file1) != 1:
            fail("file1 must be a single file or a target that provides a DirectoryPathInfo")
        file1 = ctx.files.file1[0]
        file1_path = _runfiles_path(file1)

    if DirectoryPathInfo in ctx.attr.file2:
        file2 = ctx.attr.file2[DirectoryPathInfo].directory
        file2_path = "/".join([_runfiles_path(file2), ctx.attr.file2[DirectoryPathInfo].path])
    else:
        if len(ctx.files.file2) != 1:
            fail("file2 must be a single file or a target that provides a DirectoryPathInfo")
        file2 = ctx.files.file2[0]
        file2_path = _runfiles_path(file2)

    if file1 == file2:
        msg = "diff_test comparing the same file %s" % file1
        fail(msg)

    if is_windows:
        test_suffix = "-test.bat"
        template = ctx.file._diff_test_tmpl_bat
    else:
        test_suffix = "-test.sh"
        template = ctx.file._diff_test_tmpl_sh

    test_bin = ctx.actions.declare_file(ctx.label.name + test_suffix)
    ctx.actions.expand_template(
        template = template,
        output = test_bin,
        substitutions = {
            "{name}": ctx.attr.name,
            "{fail_msg}": ctx.attr.failure_message,
            "{file1}": file1_path,
            "{file2}": file2_path,
            "{build_file_path}": ctx.build_file_path,
        },
        is_executable = True,
    )

    return DefaultInfo(
        executable = test_bin,
        files = depset(direct = [test_bin]),
        runfiles = ctx.runfiles(files = [test_bin, file1, file2]),
    )

_diff_test = rule(
    attrs = {
        "failure_message": attr.string(),
        "file1": attr.label(
            allow_files = True,
            mandatory = True,
        ),
        "file2": attr.label(
            allow_files = True,
            mandatory = True,
        ),
        "_windows_constraint": attr.label(default = "@platforms//os:windows"),
        "_diff_test_tmpl_sh": attr.label(
            default = ":diff_test_tmpl.sh",
            allow_single_file = True,
        ),
        "_diff_test_tmpl_bat": attr.label(
            default = ":diff_test_tmpl.bat",
            allow_single_file = True,
        ),
    },
    test = True,
    implementation = _diff_test_impl,
)

def diff_test(name, file1, file2, size = None, timeout = None, **kwargs):
    """A test that compares two files.

    The test succeeds if the files' contents match.

    Args:
      name: The name of the test rule.
      file1: Label of the file to compare to <code>file2</code>.
      file2: Label of the file to compare to <code>file1</code>.
      size: standard attribute for tests
      timeout: standard attribute for tests. Defaults to "short" if both timeout and size are unspecified.
      **kwargs: The <a href="https://docs.bazel.build/versions/main/be/common-definitions.html#common-attributes-tests">common attributes for tests</a>.
    """

    _diff_test(
        name = name,
        file1 = file1,
        file2 = file2,
        size = size,
        timeout = default_timeout(size, timeout),
        **kwargs
    )
