# Copyright 2020 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 testing Recipes."""

from recipe_engine.recipe_api import Property

DEPS = [
    "fuchsia/build_input_resolver",
    "fuchsia/checkout",
    "fuchsia/commit_queue",
    "fuchsia/recipe_testing",
    "fuchsia/status_check",
    "recipe_engine/buildbucket",
    "recipe_engine/context",
    "recipe_engine/json",
    "recipe_engine/path",
    "recipe_engine/properties",
    "recipe_engine/step",
]

PROPERTIES = {
    "project": Property(kind=str, help="Jiri remote manifest project", default=None),
    "manifest": Property(kind=str, help="Jiri manifest to use"),
    "remote": Property(kind=str, help="Remote manifest repository"),
    "unittest_only": Property(kind=bool, help="Finish after unit tests", default=False),
    "use_buildbucket": Property(
        kind=bool,
        help="Launch tryjobs through Buildbucket API instead of led",
        default=False,
    ),
    "include_includable_only": Property(
        kind=bool, help="Include includable_only tryjobs", default=True,
    ),
    "include_public": Property(kind=bool, help="Include public tryjobs", default=True),
    "include_private": Property(
        kind=bool, help="Include private tryjobs", default=False
    ),
    "commit_queue_project": Property(
        kind=str, help="Commit queue project", default="fuchsia"
    ),
    "check_deps": Property(
        kind=bool,
        help="Whether to check for out-of-order and unused recipe deps",
        default=False,
    ),
}

# If this build is being triggered from a change to this recipe, we need
# to explicitly pass a CL. The most recent passing run of
# fuchsia.try/recipes could take anywhere from about three to 200 minutes,
# and the three minute version does not test much of what this recipe
# actually does. In that case alter the recipes build to run on a specific
# CL that modifies the cobalt recipe alone. (The cobalt build usually
# takes less than 10 minutes.)
SELFTEST_CL = "https://fuchsia-review.googlesource.com/c/infra/recipes/+/303171"

# If this build is being triggered from a change to this recipe, and we're
# using the Buildbucket testing codepath, then we need to explicitly pass a
# builder. This builder will run in the case that the only affected recipe is
# this one, so we are guaranteed to exercise the scheduling codepath without
# recursing infinitely.
SELFTEST_BUILDER = "fuchsia/try/bringup.x64-debug-no_opt-build_only"


def RunSteps(
    api,
    project,
    manifest,
    remote,
    unittest_only,
    use_buildbucket,
    include_includable_only,
    include_public,
    include_private,
    commit_queue_project,
    check_deps,
):
    """Run tests for recipes."""

    # Resolve the build input to always contain a Gitiles commit.
    api.build_input_resolver.resolve()

    with api.context(infra_steps=True):
        api.checkout.with_options(
            path=api.path["start_dir"],
            manifest=manifest,
            remote=remote,
            project=project,
            # Override defaults. We should always attempt to patch.
            skip_patch_projects=(),
        )

    recipes_path = api.path["start_dir"].join("infra", "recipes")

    if check_deps:
        with api.context(cwd=recipes_path):
            run_check_deps(api, recipes_path)

    with api.step.defer_results():
        # TODO(olivernewman): Stop allowlisting pipes after it's no longer used by
        # gcc_toolchain.
        api.recipe_testing.run_lint(recipes_path, allowlist=r"^pipes$")
        api.recipe_testing.run_unit_tests(recipes_path)

    if not unittest_only:
        api.recipe_testing.projects = (commit_queue_project,)
        api.recipe_testing.run_tests(
            recipes_path,
            SELFTEST_CL,
            include_includable_only=include_includable_only,
            include_public=include_public,
            include_private=include_private,
            use_buildbucket=use_buildbucket,
            selftest_builder=SELFTEST_BUILDER,
        )


def run_check_deps(api, recipes_path):
    step = api.step(
        "check deps",
        [
            recipes_path.join("scripts", "cleanup_deps.py"),
            "--check",
            "--json-output",
            api.json.output(),
        ],
        ok_ret=(0, 1),
        step_test_data=lambda: api.json.test_api.output([]),
    )
    if not step.retcode:
        return

    step.presentation.status = api.step.FAILURE
    bad_files = step.json.output
    summary = (
        "Files with malformatted DEPS (run ./scripts/cleanup_deps.py to fix):\n\n"
        + "\n".join(["- `%s`" % path for path in bad_files])
    )
    raise api.step.StepFailure(summary)


def GenTests(api):  # pylint: disable=invalid-name
    def test(name, status="success", run_tests=True, **props):
        ret = (
            api.status_check.test(name, status=status)
            + api.buildbucket.try_build(
                git_repo="https://fuchsia.googlesource.com/infra/recipes"
            )
            + api.properties(
                manifest="manifest/minimal",
                remote="https://fuchsia.googlesource.com/infra/recipes",
                check_deps=True,
                **props
            )
        )
        if run_tests:
            ret += api.commit_queue.test_data() + api.recipe_testing.affected_recipes_data(
                ["none"]
            )
        return ret

    yield (
        test("cq_try")
        + api.recipe_testing.build_data(
            "fuchsia/try/fuchsia-x64-debug", "fuchsia", skip=True
        )
        + api.recipe_testing.build_data(
            "fuchsia/try/fuchsia-arm64-debug", "fuchsia", skip=True
        )
        + api.recipe_testing.build_data(
            "fuchsia/try/cobalt-x64-linux", "cobalt", skip=True
        )
    )

    yield (
        test("cq_try_private", include_public=False, include_private=True)
        + api.recipe_testing.build_data("fuchsia/try/secret-tryjob", "docs", skip=True)
    )

    yield (
        test("check_deps_fails", run_tests=False, status="failure")
        + api.step_data("check deps", api.json.output(["recipes/foo.py"]), retcode=1)
    )
