# 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 urlparse import urlparse

from PB.recipes.fuchsia.run_script import InputProperties

DEPS = [
    "fuchsia/auto_roller",
    "fuchsia/gerrit",
    "fuchsia/git",
    "fuchsia/repo",
    "fuchsia/sso",
    "fuchsia/status_check",
    "recipe_engine/buildbucket",
    "recipe_engine/cipd",
    "recipe_engine/context",
    "recipe_engine/file",
    "recipe_engine/path",
    "recipe_engine/properties",
    "recipe_engine/python",
    "recipe_engine/step",
]

PROPERTIES = InputProperties


def RunSteps(api, props):
    checkout_dir = api.path["start_dir"].join("checkout")
    with api.step.nest("checkout"), api.context(infra_steps=True):
        if props.checkout_with_repo:
            # For repo checkouts, Git must be configured to rewrite SSO URLs to
            # HTTPS.
            if props.remote.startswith("sso://"):
                api.sso.configure_insteadof(props.remote)
            api.repo.checkout_from_build_input(
                props.remote,
                path=checkout_dir,
                fallback_ref=props.fallback_ref,
            )
        else:
            api.git.checkout_from_build_input(
                repo=props.remote,
                path=checkout_dir,
                fallback_ref=props.fallback_ref,
            )

    with api.context(cwd=checkout_dir):
        script_args = list(props.script_args)
        if props.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 (
                api.buildbucket.build.input.gitiles_commit.project
            ), "we should only be uploading in CI"
            cipd_yaml_manifest = api.path.mkstemp("cipd_manifest")
            script_args += ["--cipd-yaml-manifest", cipd_yaml_manifest]

        step_name = "run %s" % props.script
        if props.script.endswith(".py"):
            # Run python scripts with vpython, rather than system Python, to
            # enable installation of packages via .vpython files.
            api.python(step_name, props.script, script_args, venv=True)
        else:
            api.step(step_name, [props.script] + script_args)

        if props.attempt_roll:
            change = api.auto_roller.attempt_roll(
                api.gerrit.host_from_remote_url(props.remote),
                gerrit_project=urlparse(props.remote).path.lstrip("/"),
                repo_dir=checkout_dir,
                commit_message='Run "%s"' % props.script,
                commit_untracked=props.roll_props.commit_untracked_files,
                dry_run=props.roll_props.dry_run,
            )
            return api.auto_roller.raw_result(change)

        if props.upload_to_cipd:
            upload_to_cipd(
                api,
                checkout_dir,
                cipd_yaml_manifest,
                set_repo_tags=props.set_repo_tags,
            )


def upload_to_cipd(api, checkout_dir, cipd_yaml_manifest, set_repo_tags=False):
    """Upload package(s) to CIPD from the script-generated CIPD .yaml manifest.

    Args:
        cipd_yaml_manifest (Path): Path to CIPD .yaml manifest.
        set_repo_tags (bool): If True, set CIPD tags based on a repo snapshot.
          Otherwise, set CIPD tags based on the input gitiles commit.
    """
    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")
    )
    if set_repo_tags:
        tags = api.repo.snapshot("repo snapshot", path=checkout_dir)
    else:
        tags = {"git_revision": api.buildbucket.build.input.gitiles_commit.id}
    for cipd_yaml_path in cipd_yaml_paths:
        api.cipd.create_from_yaml(
            checkout_dir.join(cipd_yaml_path),
            refs=["latest"],
            tags=tags,
        )


def GenTests(api):
    remote = "https://fuchsia.googlesource.com/foo"
    sso_remote = "sso://fuchsia/foo"

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

    yield (
        api.status_check.test("ci_with_repo")
        + api.properties(
            script="run-tests.sh",
            remote=remote,
            checkout_with_repo=True,
            upload_to_cipd=True,
            set_repo_tags=True,
        )
        + api.buildbucket.ci_build(git_repo=remote)
        + api.repo.snapshot("repo snapshot", ["projectA", "projectB"])
    )

    yield (
        api.status_check.test("sso")
        + api.properties(
            script="run-tests.py",
            remote=sso_remote,
            checkout_with_repo=True,
            script_args=["-flag", "flagval"],
        )
        + api.buildbucket.ci_build(git_repo=remote)
    )

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

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

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

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

    yield (
        api.status_check.test("attempt_roll")
        + api.properties(script="update.sh", remote=remote, attempt_roll=True)
        + api.auto_roller.success()
    )
