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

def black(ctx):
    tools_dir = _install_tools(ctx)

    py_files = [
        f
        for f in ctx.scm.affected_files()
        if f.endswith(".py") and
           # recipes.py is vendored from the recipe engine and should be
           # ignored.
           f != "recipes.py"
    ]
    if not py_files:
        return

    original_contents = {}
    procs = {}
    for filepath in py_files:
        original = str(ctx.io.read_file(filepath))
        original_contents[filepath] = original
        procs[filepath] = ctx.os.exec([tools_dir + "/black", "-"], stdin = original)

    for filepath, proc in procs.items():
        res = proc.wait()
        original = original_contents[filepath]
        if res.stdout != original:
            ctx.emit.finding(
                filepath = filepath,
                level = "error",
                replacements = [res.stdout],
            )

def proto_format(ctx):
    tools_dir = _install_tools(ctx)

    procs = []
    for p in ctx.scm.affected_files():
        if not p.endswith(".proto"):
            continue

        # TODO(olivernewman): Use a single `buf format` invocation and the
        # --diff option once shac knows how to parse diffs.
        cmd = [
            tools_dir + "/buf",
            "format",
            "--exit-code",
            p,
        ]
        procs.append((p, ctx.os.exec(cmd, ok_retcodes = [0, 100])))

    for p, proc in procs:
        res = proc.wait()
        if res.retcode == 100:
            ctx.emit.finding(
                filepath = p,
                level = "error",
                replacements = [res.stdout],
            )

def proto_field_numbering(ctx):
    """Checks that recipe property protobuf files have clean field numbers.

    Recipe property protos need not subscribe to normal protobuf maintenance
    conventions such as never deleting fields or changing field numbers, because
    they are only used to de/serialize JSON-encoded protos, never binary-encoded
    protos.

    So it's safe (and required, for code cleanliness) to keep proto fields
    monotonically increasing with no jumps.

    Args:
        ctx: A ctx instance.
    """
    for f in ctx.scm.affected_files():
        # The recipe_proto directory contains protos that may be used in other
        # places than just recipe properties, so we cannot safely renumber their
        # fields.
        if not f.endswith(".proto") or f.startswith("recipe_proto/"):
            continue
        res = ctx.os.exec(
            [
                "python3",
                "scripts/renumber_proto_fields.py",
                "--dry-run",
                f,
            ],
        ).wait()
        if res.stdout != str(ctx.io.read_file(f)):
            ctx.emit.finding(
                filepath = f,
                level = "error",
                replacements = [res.stdout],
            )

def _install_tools(ctx):
    install_dir = ctx.scm.root + "/.tools"
    ctx.os.exec(
        ["scripts/install-shac-tools.sh", install_dir],
        allow_network = True,
    ).wait()
    return install_dir

def check_deps(ctx):
    res = ctx.os.exec(
        [
            "python3",
            "scripts/cleanup_deps.py",
            "--check",
            "--json-output",
            "-",
        ],
        ok_retcodes = [0, 65],
    ).wait()
    if res.retcode == 65:
        for file in json.decode(res.stdout):
            # TODO(olivernewman): Parse the diff so fixes can be applied with
            # `shac fix`.
            ctx.emit.finding(
                filepath = file,
                message = "DEPS are malformatted. Run ./scripts/cleanup_deps.py to fix.",
                level = "error",
            )

def recipe_style_guide(ctx):
    """Enforces http://go/fuchsia-recipe-docs#style-guide."""
    procs = []
    for f in ctx.scm.affected_files():
        if f.endswith(".json") and ".expected" in f:
            test_name = f.split("/")[-1].rsplit(".", 1)[0]
            if " " in test_name:
                # It would be nicer to parse the recipe file to find test case
                # names because then we could emit the finding at the place
                # where the test name is defined. But because tests are
                # generated by arbitrary Python code, it's practically
                # impossible to parse out their names in a foolproof way.
                ctx.emit.finding(
                    filepath = f,
                    message = "Test name %r should not contain spaces" % test_name,
                    level = "error",
                )

        if not f.endswith(".py"):
            continue
        procs.append(ctx.os.exec(["python3", "scripts/enforce_style_guide.py", f]))

    for proc in procs:
        res = proc.wait()
        for finding in json.decode(res.stdout):
            ctx.emit.finding(**finding)

shac.register_check(shac.check(black, formatter = True))
shac.register_check(shac.check(proto_format, formatter = True))
shac.register_check(shac.check(proto_field_numbering, formatter = True))

shac.register_check(check_deps)
shac.register_check(recipe_style_guide)
