# Copyright 2023 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

# keep-sorted start
load("./cml.star", "register_cml_checks")
load("./common.star", "FORMATTER_MSG", "cipd_platform_name", "get_fuchsia_dir", "os_exec")
load("./dart.star", "register_dart_checks")
load("./docs.star", "register_doc_checks")
load("./fidl.star", "register_fidl_checks")
load("./go.star", "register_go_checks")
load("./json.star", "register_json_checks")
load("./keep_sorted.star", "keep_sorted")
load("./owners.star", "register_owners_checks")
load("./python.star", "register_python_checks")
load("./rust.star", "register_rust_checks")
load("./starlark.star", "register_starlark_checks")
# keep-sorted end

def bug_urls(ctx):
    """Checks that fuchsia bug URLs are correctly formatted.

    Bug URLs should use the form "https://fxbug.dev/42074375"; the form
    "http://fxb/123456" isn't usable by non-Google employees, and
    "fxbug.dev/42074375" doesn't automatically linkify in most editors.

    Args:
        ctx: A ctx instance.
    """
    correct_format = "https://fxbug.dev/"
    for f, meta in ctx.scm.affected_files().items():
        for num, line in meta.new_lines():
            for match in ctx.re.allmatches(
                r"(https?://)?fxb(ug\.dev)?/(\d+)",
                line,
            ):
                if match.groups[0].startswith(correct_format):
                    continue
                bug_number = match.groups[-1]
                repl = correct_format + bug_number
                ctx.emit.finding(
                    level = "warning",
                    message = "Bug links should use the form %s." % repl,
                    filepath = f,
                    line = num,
                    col = match.offset + 1,
                    end_col = match.offset + 1 + len(match.groups[0]),
                    replacements = [repl],
                )

def _gn_format(ctx):
    """Runs gn format on .gn and .gni files.

    Args:
        ctx: A ctx instance.
    """
    gn_files = [
        f
        for f in ctx.scm.affected_files()
        if f.endswith((".gn", ".gni"))
    ]
    if not gn_files:
        return

    gn = "%s/prebuilt/third_party/gn/%s/gn" % (get_fuchsia_dir(ctx), cipd_platform_name(ctx))

    result = os_exec(
        ctx,
        [gn, "format", "--dry-run"] + gn_files,
        ok_retcodes = [0, 1, 2],
    ).wait()

    if result.retcode in [0, 2]:
        unformatted_files = result.stdout.splitlines()
        for f in unformatted_files:
            formatted_contents = os_exec(
                ctx,
                [gn, "format", "--stdin"],
                stdin = ctx.io.read_file(f),
            ).wait().stdout
            ctx.emit.finding(
                level = "error",
                message = FORMATTER_MSG,
                filepath = f,
                replacements = [formatted_contents],
            )

        # If gn format --dry-run command fails, we can't filter a list of unformatted files, so we iterate over all the files
    elif result.retcode == 1:
        for f in gn_files:
            res = os_exec(
                ctx,
                [gn, "format", "--stdin"],
                stdin = ctx.io.read_file(f),
                ok_retcodes = [0, 1, 2],
            ).wait()
            if res.retcode == 1:
                finding = res.stdout
                fail("{}: {}".format(f, finding))

# TODO(https://fxbug.dev/326595281): Delete this check once submodules are
# source-of-truth and enabled unconditionally.
def test_submodule_contents(ctx):
    """Spits out the contents of the test submodule's README."""
    if ctx.scm.root != get_fuchsia_dir(ctx):
        return
    readme_path = "infra/testproject/README.md"
    msg = os_exec(
        ctx,
        [
            "%s/prebuilt/third_party/python3/%s/bin/python3" % (
                get_fuchsia_dir(ctx),
                cipd_platform_name(ctx),
            ),
            "scripts/shac/test_submodule_contents.py",
            readme_path,
        ],
    ).wait().stdout
    ctx.emit.finding(
        level = "notice",
        message = msg,
        # Arbitrary file that's in the main checkout so that top-level comments
        # for this check don't get added to CLs.
        filepath = "infra/README.md",
    )

def register_all_checks():
    """Register all checks that should run.

    Checks must be registered in a callback function because they can only be
    registered by the root shac.star file, not at the top level of any `load`ed
    file.
    """
    shac.register_check(shac.check(_gn_format, formatter = True))
    shac.register_check(keep_sorted)
    shac.register_check(bug_urls)
    shac.register_check(test_submodule_contents)

    # keeps-sorted start
    register_cml_checks()
    register_dart_checks()
    register_doc_checks()
    register_fidl_checks()
    register_go_checks()
    register_json_checks()
    register_owners_checks()
    register_python_checks()
    register_rust_checks()
    register_starlark_checks()
    # keeps-sorted end
