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

# A general-purpose recipe for uploading third-party prebuilts to CIPD.
#
# This recipe assumes that
# (1) everything needed to produce a prebuilt can be obtained from a given
#     jiri checkout.
# (2) in that checkout, a JSON file of "contents" is found that describes all
#     of the file i/o that the recipe should perform from the checkout to a
#     staging directory. The schema is that of CONTENTS_JSON_TEST_DATA below.
# (3) also in that checkout, there is a script that takes a single positional
#     argument of a directory that it is meant to populate; this directory
#     will be uploaded to CIPD after script invocation. The script may assume
#     that the above staging directory will be set as its CWD.
#

from PB.recipes.fuchsia.contrib.third_party_prebuilts import InputProperties

DEPS = [
    "fuchsia/buildbucket_util",
    "fuchsia/cas_util",
    "fuchsia/checkout",
    "fuchsia/cipd_util",
    "recipe_engine/context",
    "recipe_engine/file",
    "recipe_engine/path",
    "recipe_engine/properties",
    "recipe_engine/step",
]

PROPERTIES = InputProperties

CONTENTS_JSON_TEST_DATA = [
    {
        # `destination` is a directory relative to the packing directory.
        "destination": "baz",
        # `files` is a list of files to move to `destination`, each relative to
        # the checkout root,
        "files": ["data/bar.txt", "data/foo.json"],
    },
]


def RunSteps(api, props):
    checkout_root = api.checkout.with_options(
        manifest=props.manifest,
        remote=props.remote,
        project=props.project,
    )
    revision = api.checkout.project(props.project, checkout_root=checkout_root)[
        "revision"
    ]

    staging_dir = api.path.mkdtemp("3p_prebuilts.staging")

    with api.step.nest("gather contents"):
        contents = api.file.read_json(
            f"read {api.path.basename(props.content_manifest)}",
            checkout_root.join(props.content_manifest),
            test_data=CONTENTS_JSON_TEST_DATA,
        )
        for entry in contents:
            rel_dest = entry["destination"]
            dest = staging_dir.join(rel_dest)
            with api.step.nest(rel_dest if rel_dest else "."):
                api.file.ensure_directory(f"ensure {rel_dest}", dest)
                for rel_src in entry["files"]:
                    src = checkout_root.join(rel_src)
                    api.file.copy(f"copy {rel_src}", src, dest)

    output_dir = api.path.mkdtemp("3p_prebuilts.output")
    with api.context(cwd=staging_dir):
        api.step(
            "pack contents", [checkout_root.join(props.packing_script), output_dir]
        )

    with api.step.nest(props.cipd_pkg_name):
        if api.buildbucket_util.is_dev_or_try:
            api.cas_util.upload(output_dir, step_name="upload prebuilts to CAS")
        else:
            api.cipd_util.upload_package(
                pkg_name=props.cipd_pkg_name,
                pkg_root=output_dir,
                search_tag={"git_revision": revision},
            )


def GenTests(api):
    properties = api.properties(
        project="third_party/prebuilts",
        manifest="third_party/prebuilts",
        remote="https://fuchsia.googlesource.com/manifest",
        packing_script="generate.sh",
        cipd_pkg_name="fuchsia/third_party/foo",
        content_manifest="contents.json",
    )

    yield api.buildbucket_util.test("try", tryjob=True) + properties
    yield api.buildbucket_util.test("ci") + properties
