# Copyright 2023 The Pigweed Authors
#
# 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
#
#     https://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.

def _get_affected_python_files(ctx):
    files = [f for f in ctx.scm.affected_files() if f.endswith(".py")]
    exclusions = [
        # recipes.py is vendored from the recipe engine and should be ignored.
        "recipes.py",
        # cleanup_deps.py and renumber_proto_fields.py are vendored from the
        # upstream Fuchsia recipes repo as-is and should not be modified.
        "scripts/cleanup_deps.py",
        "scripts/renumber_proto_fields.py",
    ]
    return [f for f in files if f not in exclusions]

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

    py_files = _get_affected_python_files(ctx)
    if not py_files:
        return

    original_contents = {}

    # First run `ruff check --fix --select=I` to sort imports, which `ruff
    # format` doesn't support.
    isort_procs = {}
    for filepath in py_files:
        original = str(ctx.io.read_file(filepath))
        original_contents[filepath] = original
        isort_procs[filepath] = ctx.os.exec(
            [
                tools_dir + "/ruff",
                "check",
                "--fix",
                # Only check import sorting.
                "--select=I",
                "--stdin-filename",
                filepath,
                "-",
            ],
            stdin = original,
        )

    # Then run `ruff format`.
    format_procs = {}
    for filepath, proc in isort_procs.items():
        res = proc.wait()
        format_procs[filepath] = ctx.os.exec(
            [
                tools_dir + "/ruff",
                "format",
                "--stdin-filename",
                filepath,
                "-",
            ],
            stdin = res.stdout,
        )

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

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

    py_files = _get_affected_python_files(ctx)
    if not py_files:
        return

    res = ctx.os.exec(
        [
            tools_dir + "/ruff",
            "check",
            "--output-format",
            "json",
            "--show-fixes",
        ] +
        py_files,
        ok_retcodes = [0, 1],
    ).wait()

    for finding in json.decode(res.stdout):
        filepath = finding["filename"]
        if filepath.startswith(ctx.scm.root):
            filepath = filepath[len(ctx.scm.root) + 1:]

        replacements = None
        if finding.get("fix") and len(finding["fix"].get("edits", [])) == 1:
            edit = finding["fix"]["edits"][0]
            start_loc, end_loc = edit["location"], edit["end_location"]
            replacements = [edit["content"]]
        else:
            start_loc, end_loc = finding["location"], finding["end_location"]

        ctx.emit.finding(
            filepath = filepath,
            message = "%s: %s" % (finding["code"], finding["message"]),
            level = "error",
            line = start_loc["row"],
            col = start_loc["column"],
            end_line = end_loc["row"],
            end_col = end_loc["column"],
            replacements = replacements,
        )

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(
        [ctx.scm.root + "/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",
            )

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

shac.register_check(ruff_lint)
shac.register_check(check_deps)
