# Copyright 2019 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 a specified script from a given repo."""

from recipe_engine.recipe_api import Property

DEPS = [
    "fuchsia/git",
    "fuchsia/status_check",
    "recipe_engine/buildbucket",
    "recipe_engine/cipd",
    "recipe_engine/context",
    "recipe_engine/file",
    "recipe_engine/path",
    "recipe_engine/properties",
    "recipe_engine/step",
    "recipe_engine/url",
]

PROPERTIES = {
    "script": Property(kind=str, help="Relative path to the script to run."),
    "upload_to_cipd": Property(
        kind=bool, help="Whether to upload a package to CIPD.", default=False
    ),
}


def RunSteps(api, script, upload_to_cipd):
    bb_input = api.buildbucket.build.input

    with api.step.nest("checkout"), api.context(infra_steps=True):
        checkout_dir = api.path["start_dir"].join(
            "run-script-%s" % api.url.quote(script.replace(".", "-"))
        )
        api.git.checkout_from_build_input(path=checkout_dir)

    with api.context(cwd=checkout_dir):
        script_cmd = [script]
        if upload_to_cipd:
            # Script must emit a newline-separated txt file of CIPD yaml paths,
            # e.g. "/path/to/foo.yaml\n/path/to/bar.yaml" relative to the
            # working dir i.e. the checkout dir.
            assert bb_input.gitiles_commit.project, "we should only be uploading in CI"
            cipd_yaml_manifest = api.path.mkstemp()
            script_cmd += ["--cipd-yaml-manifest", cipd_yaml_manifest]

        api.step("run %s" % script, script_cmd)

        if upload_to_cipd:
            # Create package(s) from the script's emitted CIPD yaml(s).
            cipd_yaml_paths = (
                api.file.read_text(
                    "read CIPD yaml manifest",
                    cipd_yaml_manifest,
                    test_data="path/to/foo.yaml\npath/to/bar.yaml\n",
                )
                .rstrip()
                .split("\n")
            )
            for cipd_yaml_path in cipd_yaml_paths:
                api.cipd.create_from_yaml(
                    checkout_dir.join(cipd_yaml_path),
                    refs=["latest"],
                    tags={"git_revision": bb_input.gitiles_commit.id},
                )


def GenTests(api):
    repo = "https://fuchsia.googlesource.com/foo"

    yield (
        api.status_check.test("ci")
        + api.properties(script="run-tests.sh")
        + api.buildbucket.ci_build(git_repo=repo)
    )

    yield (
        api.status_check.test("ci_upload")
        + api.properties(script="build-pkg.sh", upload_to_cipd=True)
        + api.buildbucket.ci_build(git_repo=repo)
    )

    yield (
        api.status_check.test("cq")
        + api.properties(script="run-tests.sh")
        + api.buildbucket.try_build(git_repo=repo)
    )

    yield (
        api.status_check.test("script_failed", status="failure")
        + api.properties(script="run-tests.sh")
        + api.buildbucket.ci_build(git_repo=repo)
        + api.step_data("run run-tests.sh", retcode=1)
    )

    yield (
        api.status_check.test("no_buildbucket_input", status="infra_failure")
        + api.properties(script="run-tests.sh")
    )
