# Copyright 2018 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.
"""Recipe for running Tricium analyzers."""

import functools

from recipe_engine.post_process import MustRun
from PB.recipes.fuchsia.tricium.tricium import InputProperties

DEPS = [
    "fuchsia/build",
    "fuchsia/buildbucket_util",
    "fuchsia/checkout",
    "fuchsia/git",
    "fuchsia/tricium_analyze",
    "recipe_engine/buildbucket",
    "recipe_engine/cipd",
    "recipe_engine/context",
    "recipe_engine/json",
    "recipe_engine/path",
    "recipe_engine/platform",
    "recipe_engine/properties",
    "recipe_engine/raw_io",
    "recipe_engine/step",
]

PROPERTIES = InputProperties

# We'll skip running checks on any files for which this git attribute is
# explicitly unset. We *will* run checks on all files for which this attribute
# is unspecified, or explicitly set.
TRICIUM_GIT_ATTR = "tricium"


def RunSteps(api, props):
    checkout = api.checkout.fuchsia_with_options(
        manifest=props.manifest,
        remote=props.remote,
        # Tricium should always be triggered on CLs that affect projects in
        # the checkout, so we shouldn't skip patching any CLs.
        skip_patch_projects=(),
        use_incremental_cache=props.incremental_build,
    )

    project_name = api.buildbucket.build.input.gerrit_changes[0].project

    # If specified, download CIPD packages.
    if props.cipd_packages:
        with api.step.nest("ensure_packages"):
            with api.context(infra_steps=True):
                cipd_dir = checkout.root_dir / "cipd"
                pkgs = api.cipd.EnsureFile()
                for package in props.cipd_packages:
                    pkgs.add_package(
                        package.name, package.version, subdir=package.subdir
                    )
                api.cipd.ensure(cipd_dir, pkgs)
                platform = "%s-%s" % (
                    api.platform.name.replace("win", "windows"),
                    {
                        "intel": {
                            32: "386",
                            # Note that this is different from the CIPD norm (this is how
                            # //prebuilt/third_party is laid out).
                            64: "x64",
                        },
                        "arm": {32: "armv6", 64: "arm64"},
                    }[api.platform.arch][api.platform.bits],
                )
                # Only these tools are being downloaded from CIPD, so directly set the
                # paths if cipd_packages is defined.
                api.tricium_analyze.go = cipd_dir.joinpath("go", platform, "bin", "go")
                api.tricium_analyze.gofmt = cipd_dir.joinpath(
                    "go", platform, "bin", "gofmt"
                )

    project_dir = api.path.abs_to_path(checkout.project(project_name)["path"])

    api.tricium_analyze.check_commit_message()

    if props.fint_params_path:
        api.tricium_analyze.build_results = api.build.with_options(
            checkout=checkout,
            fint_params_path=props.fint_params_path,
            incremental=props.incremental_build,
        )

    with api.context(cwd=project_dir):
        paths = api.git.get_changed_files(
            "get changed files",
        )
        with api.step.nest("filter tricium-disabled files"):
            paths = filter_by_git_attrs(api, paths)

        api.tricium_analyze.suggest_fx = api.path.exists(
            checkout.root_dir.joinpath("scripts", "fx")
        )
        api.tricium_analyze.checkout = checkout
        api.tricium_analyze(
            paths,
            enabled_analyzers=props.analyses,
            enabled_luci_analyzers=props.luci_analyzers,
        )


def filter_by_git_attrs(api, paths):
    """Remove files that have Tricium disabled by a git attribute."""
    filtered_files = []
    # Process long lists of files in chunks to avoid exceeding command length
    # limits. Arbitrarily chosen chunk size that's likely to not exceed the
    # limit.
    chunk_size = 100
    for i in range(0, len(paths), chunk_size):
        chunk = paths[i : i + chunk_size]
        mock_output = "\0".join(
            [f"{f}\x00{TRICIUM_GIT_ATTR}\x00unspecified" for f in chunk]
        )
        step = api.git(
            f"check git attributes for files {int(i)}-{int(i + len(chunk))}",
            "check-attr",
            # Separate records with nuls, to prevent ugly escaping of non-ASCII
            # filenames.
            "-z",
            TRICIUM_GIT_ATTR,
            "--",
            *chunk,
            stdout=api.raw_io.output_text(),
            # Use functools.partial instead of a lambda to avoid Pylint's
            # cell-var-from-loop warning.
            step_test_data=functools.partial(
                api.raw_io.test_api.stream_output_text, mock_output
            ),
        )
        raw_records = step.stdout.strip("\0").split("\0")
        attr_statuses = [raw_records[i : i + 3] for i in range(0, len(raw_records), 3)]
        step.presentation.logs["file attributes"] = api.json.dumps(
            attr_statuses, indent=2
        ).splitlines()
        for filename, _, status in attr_statuses:
            if status != "unset":
                filtered_files.append(filename)

    return filtered_files


def GenTests(api):
    DIFF = """diff --git a/{0} b/{0}
index e684c1e..a76a10e 100644
--- a/{0}
+++ b/{0}
@@ -1,2 +1,4 @@
+  foo
+  bar
"""

    def changed_files_data(files):
        return api.git.get_changed_files("get changed files", files)

    def change_diff_data(filename):
        return api.step_data(
            f"analyze {filename}.get change diff",
            api.raw_io.stream_output_text(DIFF.format(filename)),
        )

    def formatted_diff_data(filename):
        return api.step_data(
            f"analyze {filename}.get formatted diff",
            api.raw_io.stream_output_text(DIFF.format(filename)),
        )

    def properties(cipd_packages=(), **kwargs):
        defaults = dict(
            manifest="flower",
            remote="https://fuchsia.googlesource.com/integration",
        )
        # Using CIPD packages implies that we don't need to do a build, and
        # vice versa.
        if cipd_packages:
            defaults["cipd_packages"] = cipd_packages
        else:
            defaults.update(fint_params_path="fint_params/tricium.textproto")
        defaults.update(kwargs)
        return api.properties(**defaults)

    yield (
        api.buildbucket_util.test("default", tryjob=True)
        + properties(
            analyses=["ClangTidy"],
            luci_analyzers=["Spellchecker"],
            incremental_build=True,
        )
    )

    yield (
        api.buildbucket_util.test("with_cipd_packages", tryjob=True)
        + properties(
            analyses=["GoFmt"],
            cipd_packages=[
                {
                    "name": "fuchsia/go/${platform}",
                    "version": "integration",
                    "subdir": "go",
                }
            ],
        )
        + changed_files_data(["BUILD.gn", "hello.go"])
        + change_diff_data("hello.go")
        + formatted_diff_data("hello.go")
    )

    yield (
        api.buildbucket_util.test("attribute_disable", tryjob=True)
        + properties(analyses=["ClangFormat"])
        + changed_files_data(["BUILD.gn", "hello.go"])
        + api.step_data(
            "filter tricium-disabled files.check git attributes for files 0-2",
            api.raw_io.stream_output_text(
                "BUILD.gn\0tricium\0unset\0hello.go\0tricium\0unspecified\0"
            ),
        )
    )

    # Even if running one analysis fails, we should still run the other
    # analyses and write their results before failing the build.
    yield (
        api.buildbucket_util.test("one_analysis_fails", tryjob=True, status="FAILURE")
        + properties(analyses=["ClangTidy"])
        + changed_files_data(["hello.cc"])
        + api.step_data("analyze hello.cc.clang-tidy.clang-tidy-diff.py", retcode=2)
        + api.post_process(MustRun, "write results")
    )
