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

"""Code for testing recipes."""

import datetime
import fnmatch
import functools

from google.protobuf import json_format as jsonpb
from google.protobuf import timestamp_pb2

from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
from PB.go.chromium.org.luci.buildbucket.proto import (
    builds_service as builds_service_pb2,
)
from PB.recipe_modules.flutter.recipe_testing import properties as properties_pb2
from recipe_engine import recipe_api
from RECIPE_MODULES.fuchsia.swarming_retry import api as swarming_retry_api


class Build(swarming_retry_api.LedTask):
    # This warning is spurious because LedTask defines _led_data.
    # pylint: disable=attribute-defined-outside-init

    def include_cl(self, cl):
        self._led_data = self._led_data.then("edit-cr-cl", cl)

    def include_recipe_bundle(self):
        self._led_data = self._led_data.then("edit-recipe-bundle")

    def use_realms(self):
        self._led_data = self._led_data.then(
            "edit", "-experiment", "luci.use_realms=true"
        )

    def set_properties(self, properties):
        args = []
        for k, v in properties.items():
            args += ["-pa", "%s=%s" % (k, self._api.json.dumps(v))]
        self._led_data = self._led_data.then("edit", *args)


def led_task_name(builder):
    """Returns the name to use for the led swarming task for the builder."""
    return "recipes-cq:%s" % builder


class RecipeTestingApi(recipe_api.RecipeApi):
    """API for running tests and processing test results."""

    def __init__(self, props, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._recipe_depth = props.recipe_depth
        self.enabled = props.enabled
        self.max_build_age_seconds = int(datetime.timedelta(days=28).total_seconds())
        self.projects = ("flutter",)

    def _get_affected_recipes(self, recipes_path):
        """Collect affected recipes.

        For now assume we care about all recipes.
        """

        with self.m.step.nest("get_affected_recipes") as parent_step:
            recipes_dir = recipes_path.join("recipes")
            recipe_files = self.m.file.listdir(
                "ls-recipes", recipes_dir, recursive=True
            )

            all_recipes = []
            for recipe_file in recipe_files:
                path = self.m.path.relpath(
                    self.m.path.realpath(recipe_file), self.m.path.realpath(recipes_dir)
                )
                # Files inside folders that end in ".resources" are never recipes.
                if self.m.path.dirname(path).endswith(".resources"):
                    continue

                name, ext = self.m.path.splitext(path)
                if ext == ".py":
                    all_recipes.append(name)

            parent_step.logs["all recipes"] = all_recipes

            with self.m.context(cwd=recipes_path):
                changed_files = self.m.git.get_changed_files(commit="HEAD")
            parent_step.logs["changed files (raw)"] = changed_files

            def is_expected_json(path):
                # We want to ignore expected JSON files--they won't affect how recipes
                # run. It's possible there are JSON files used as data for recipes
                # instead of as expected test outputs, so determine which files to
                # ignore very narrowly.
                return self.m.path.splitext(path)[1] == ".json" and self.m.path.dirname(
                    path
                ).endswith(".expected")

            def is_python_test_file(path):
                """Return True if this is a test file that we should ignore."""
                # We want to ignore test_api.py files--they won't affect how recipes
                # run in led, they only affect how recipes run in
                # './recipes test run', and we test that every time any recipe is
                # changed.
                if (
                    self.m.path.basename(path) == "test_api.py"
                    and self.m.path.dirname(self.m.path.dirname(path))
                    == "recipe_modules"
                ):
                    return True

                # Also ignore test definitions themselves. By convention these are
                # given the filename 'full.py' in Fuchsia, but there is no
                # guarantee this will remain the case.
                test_dir_names = ("tests", "examples")
                if (
                    self.m.path.splitext(path)[1] == ".py"
                    and self.m.path.basename(self.m.path.dirname(path))
                    in test_dir_names
                ):
                    return True

                return False

            def is_ignored_file(path):
                return is_expected_json(path) or is_python_test_file(path)

            filtered_changed_files = [
                x for x in changed_files if not is_ignored_file(x)
            ]
            parent_step.logs["changed files (filtered)"] = filtered_changed_files or [
                "no changed files"
            ]

            res = self.m.step(
                "recipes-analyze",
                [
                    recipes_path.join("recipes.py"),
                    "analyze",
                    self.m.json.input(
                        {"recipes": all_recipes, "files": filtered_changed_files}
                    ),
                    self.m.json.output(),
                ],
            )

            affected_recipes = res.json.output["recipes"]

            def should_test_all_recipes(path):
                globs = (
                    "infra/config/recipes.cfg",
                    # We particularly care about running CQ for flutter.proto changes.
                    "recipe_proto/*.proto",
                )
                return any(fnmatch.fnmatch(path, glob) for glob in globs)

            special_changed_files = [
                f for f in changed_files if should_test_all_recipes(f)
            ]
            if special_changed_files:
                step = self.m.step.empty("mark all recipes as affected")
                step.presentation.step_summary_text = (
                    "because these files were changed:"
                )
                step.presentation.step_text = "\n" + "\n".join(special_changed_files)
                affected_recipes = all_recipes

            parent_step.logs["affected recipes"] = affected_recipes

            # Skip running recipes in the `recipes/contrib` directory, because
            # they are generally lower-priority and not worth running by default
            # in recipes CQ.
            return {r for r in affected_recipes if not r.startswith("contrib/")}

    def _get_last_green_build(self, builder):
        """Returns the build proto for a builder's most recent successful build.

        If no build younger than `self.max_build_age_seconds` is found, returns
        None.

        Args:
          builder: builder protobuf object
        """
        project, bucket, builder = builder.split("/")
        # "infra" is not returned by default, so we have to specify it.
        build = self.m.buildbucket_util.last_build(
            project, bucket, builder, status=common_pb2.SUCCESS
        )
        if not build:
            return None

        age_seconds = self.m.time.time() - build.end_time.seconds
        if age_seconds > self.max_build_age_seconds:
            return None
        return build

    def _create_led_build(self, orig_build, selftest_cl):
        builder = orig_build.builder
        builder_lookup_name = "{project}/{bucket}:{builder}".format(
            project=builder.project,
            bucket=builder.bucket,
            builder=builder.builder,
        )
        # Using `led get-builder` instead of `led get-build` ensures that we
        # won't use an outdated version of the builder (e.g. with deprecated
        # dimensions).
        # By default the priority is increased by 10 (resulting in a "lower"
        # priority), but we want it to stay the same.
        led_data = self.m.led(
            "get-builder", "-adjust-priority", "0", builder_lookup_name
        )

        led_data = led_data.then("edit", "-name", led_task_name(builder.builder))
        build = Build(api=self.m, name=builder.builder, led_data=led_data)

        if orig_build.input.properties["recipe"] == "recipes":
            build.include_cl(selftest_cl)
        elif orig_build.input.gerrit_changes:
            orig_cl = orig_build.input.gerrit_changes[0]
            cl_id, patchset = self._get_latest_cl(orig_cl.host, orig_cl.project)
            # Setting the CL to a more recent CL helps avoid rebase errors, but
            # if unable to find a recent CL, fall back to the original build's
            # triggering CL. It usually works.
            if not cl_id:
                cl_id = orig_cl.change
                patchset = orig_cl.patchset
            url = "https://%s/c/%s/+/%d/%d" % (
                orig_cl.host,
                orig_cl.project,
                cl_id,
                patchset,
            )
            build.include_cl(url)
        build.set_properties(self._tryjob_properties())
        build.use_realms()

        return build

    @functools.lru_cache(maxsize=None)
    def _get_latest_cl(self, gerrit_host, project):
        """Returns number and patchset for a project's most recently landed CL.

        Args:
          gerrit_host (str): E.g., flutter-review.googlesource.com
          project (str): The name of the project in gerrit, e.g. "flutter"

        Returns:
          A tuple of
          * The integer change number for the CL corresponding to the commit at
            the tip of the main branch.
          * The last patchset of that CL.
        """
        gitiles_host = gerrit_host.replace("-review", "")
        remote = "https://%s/%s" % (gitiles_host, project)
        ref = self.m.git.get_default_remote_branch(remote)
        log = self.m.gitiles.log(remote, ref, limit=10, step_name="log %s" % project)

        for log_entry in log:
            commit_hash = log_entry["id"]
            step = self.m.gerrit.change_details(
                "latest change details for %s" % project,
                commit_hash,
                query_params=("CURRENT_REVISION",),
                host=gerrit_host,
                test_data=self.m.json.test_api.output(
                    {
                        "_number": 12345,
                        "current_revision": "5" * 40,
                        "revisions": {"5" * 40: {"_number": 6}},
                    }
                ),
                ok_ret=(0, 1),
            )
            # A commit that is committed directly without code review won't have a
            # corresponding Gerrit CL, so fetching it will fail (which is fine, we'll
            # just skip it and try the next one).
            if step.retcode == 0:
                cl_number = step.json.output["_number"]
                rev = step.json.output["current_revision"]
                ps_number = step.json.output["revisions"][rev]["_number"]
                return (cl_number, ps_number)
        return None, None

    def run_lint(self, recipes_path, allowlist=""):
        """Run lint on recipes.

        Args:
          recipes_path (Path): The path to the root of the recipes repo.
          allowlist (str): A regex of import names to allow.
        """
        args = ["lint"]
        if allowlist:
            args.extend(["--allowlist", allowlist])
        with self.m.context(cwd=recipes_path):
            self.m.step(
                "lint",
                cmd=[self.m.context.cwd.join("recipes.py")] + args,
            )

    def run_unit_tests(self, recipes_path):
        """Run the recipe unit tests."""
        with self.m.context(cwd=recipes_path):
            self.m.step(
                "test",
                cmd=[
                    self.m.context.cwd.join("recipes.py"),
                    "test",
                    "run",
                ],
            )

    def run_tests(
        self,
        recipes_path,
        selftest_cl,
        config,
        selftest_builder=None,
    ):
        """Launch CQ builders.

        Args:
          recipes_path (Path): Path to recipes repo checkout.
          selftest_cl (str): The CL to use to test a recursive recipe testing
            invocation.
          config (RecipeTesting proto): Many options for led/bb tests.
            TODO(fxbug.dev/88439): Make this a formal proto under
            recipe_modules/recipe_testing.
          selftest_builder (str|None): Builder to use to guarantee that we
            exercise the scheduling codepath when `use_buildbucket` is True.
        """
        # When run against a change to the recipes recipe, this is what the
        # swarming task stack should look like:
        #
        # * recipes.py from current recipe bundle, run against current CL
        # * recipes.py from current CL, run against SELFTEST_CL
        # * cobalt.py from current CL, run against current CL
        #
        # This works, but in case something goes wrong we need to make sure we
        # don't enter infinite recursion. We should never get to a third call to
        # recipes.py, so if we do we should exit.
        if self._recipe_depth >= 2:
            raise self.m.step.InfraFailure("recursion limit reached")

        builders = set()
        for project in config.projects:
            project_builders = set(
                self.m.commit_queue.all_tryjobs(
                    project=project.name,
                    include_unrestricted=project.include_unrestricted,
                    include_restricted=project.include_restricted,
                    config_name=project.cq_config_name or "commit-queue.cfg",
                )
            )

            for excluded_bucket in project.excluded_buckets:
                excluded_builders = set()
                for builder in project_builders:
                    # Retrieve "<bucket>" from "<project>/<bucket>/<builder>".
                    bucket = builder.split("/")[1]
                    if bucket == excluded_bucket:
                        excluded_builders.add(builder)

                if excluded_builders:
                    project_builders -= excluded_builders
                    with self.m.step.nest(
                        "excluding {} builders from bucket {}/{}".format(
                            len(excluded_builders),
                            project.name,
                            excluded_bucket,
                        )
                    ) as pres:
                        pres.step_summary_text = "\n".join(sorted(excluded_builders))

            builders.update(project_builders)

        builders = sorted(builders)

        affected_recipes = self._get_affected_recipes(recipes_path=recipes_path)
        if not affected_recipes:
            return

        if config.use_buildbucket:
            self._run_buildbucket_tests(selftest_builder, builders, affected_recipes)
        else:
            self._run_led_tests(recipes_path, selftest_cl, builders, affected_recipes)

    def _is_build_affected(self, orig_build, affected_recipes, presentation):
        if not orig_build:
            presentation.step_summary_text = "no recent builds found"
            return False

        recipe = orig_build.input.properties["recipe"]
        assert recipe

        is_recipe_affected = recipe in affected_recipes
        presentation.step_summary_text = "SELECTED" if is_recipe_affected else "skipped"
        presentation.logs["recipe_used"] = recipe
        return is_recipe_affected

    def _get_green_tryjobs(self, expiry_secs=24 * 60 * 60):
        """Return the set of tryjobs that are green on the current patchset.

        Args:
          expiry_secs (int): Do not return tryjobs which are older than this
            value in seconds.
        """
        builds = self.m.buildbucket.search(
            builds_service_pb2.BuildPredicate(
                gerrit_changes=list(self.m.buildbucket.build.input.gerrit_changes),
                status=common_pb2.SUCCESS,
                create_time=common_pb2.TimeRange(
                    start_time=timestamp_pb2.Timestamp(
                        seconds=int(self.m.time.time()) - expiry_secs,
                    ),
                ),
            ),
            fields=["builder"],
            step_name="get green tryjobs",
        )
        return {self.m.buildbucket_util.full_builder_name(b.builder) for b in builds}

    def _run_buildbucket_tests(self, selftest_builder, builders, affected_recipes):
        affected_builders = []
        recipes_is_affected = False

        with self.m.step.nest("get builders"), self.m.context(infra_steps=True):
            green_tryjobs = self._get_green_tryjobs()
            builders = [b for b in builders if b not in green_tryjobs]
            for builder in builders:
                with self.m.step.nest(builder) as presentation:
                    orig_build = self._get_last_green_build(builder)
                    if self._is_build_affected(
                        orig_build, affected_recipes, presentation
                    ):
                        # With recipe versioning, the `recipes` recipe is
                        # already tested in this invocation, so don't schedule
                        # any more `recipes` builds.
                        if orig_build.input.properties["recipe"] == "recipes":
                            recipes_is_affected = True
                            continue
                        affected_builders.append(builder)

        # If `affected_builders` is empty, but the current recipe was affected,
        # then we should schedule one self-test builder so we can still exercise
        # the scheduling codepath.
        if not affected_builders and recipes_is_affected:
            affected_builders = [selftest_builder]

        with self.m.step.nest("launch builds") as presentation:
            builds = self.m.subbuild.launch(
                # TODO(atyfto): Fix subbuild.launch so it can accept builders
                # with `bucket`s and/or `project`s which don't necessarily match
                # the current build's.
                builder_names=[b.split("/")[-1] for b in affected_builders],
                extra_properties=self._tryjob_properties(),
                presentation=presentation,
                # Present tryjobs in Gerrit since they are effectively
                # top-level builds.
                hide_in_gerrit=False,
            )
        with self.m.step.nest("collect builds"):
            results = self.m.subbuild.collect(
                build_ids=[b.build_id for b in builds.values()],
            )
            self.m.buildbucket_util.display_builds(
                "check builds",
                [b.build_proto for b in results.values()],
                raise_on_failure=True,
            )

    def _run_led_tests(self, recipes_path, selftest_cl, builders, affected_recipes):
        builds = []
        with self.m.step.nest("get builders") as nest, self.m.context(
            cwd=recipes_path, infra_steps=True
        ):
            for builder in builders:
                with self.m.step.nest(builder) as presentation:
                    orig_build = self._get_last_green_build(builder)
                    if self._is_build_affected(
                        orig_build, affected_recipes, presentation
                    ):
                        build = self._create_led_build(orig_build, selftest_cl)
                        build.include_recipe_bundle()
                        builds.append(build)

            nest.step_summary_text = "selected {} builds".format(len(builds))

        if not builds:
            return

        self.m.swarming_retry.run_and_present_tasks(builds)

    def _tryjob_properties(self):
        """Properties that should be set on each launched tryjob."""
        props = properties_pb2.InputProperties(
            # Signal to the launched build that it's being tested by this module.
            enabled=True,
            # Increment the recipe depth. This only has an effect on builds that
            # use this module.
            recipe_depth=self._recipe_depth + 1,
        )
        return {
            "$flutter/recipe_testing": jsonpb.MessageToDict(
                props, preserving_proto_field_name=True
            )
        }
