# Copyright 2018 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 building and publishing CIPD prebuilts."""

from PB.recipes.fuchsia.prebuilt_host_tool import InputProps

DEPS = [
    "fuchsia/build",
    "fuchsia/buildbucket_util",
    "fuchsia/checkout",
    "fuchsia/gsutil",
    "fuchsia/status_check",
    "fuchsia/upload",
    "recipe_engine/buildbucket",
    "recipe_engine/path",
    "recipe_engine/properties",
]

PROPERTIES = InputProps


def RunSteps(api, props):
    checkout = api.checkout.fuchsia_with_options(
        path=api.path["start_dir"], manifest=props.manifest, remote=props.remote
    )

    build_results = api.build.with_options(
        checkout=checkout, fint_params_path=props.fint_params_path
    )

    if not api.buildbucket_util.is_tryjob:
        revision = str(api.buildbucket.build.input.gitiles_commit.id)
        assert revision
        for tool in props.tools:
            path = build_results.tool(tool.name)
            if tool.cipd_package:
                upload_to_cipd(api, tool, path, props.remote, revision)
            if tool.gcs_bucket:
                upload_to_gcs(api, tool, path)


def upload_to_cipd(api, tool, path, remote, revision):
    assert tool.cipd_package.endswith("/${platform}"), (
        "package %s must have a ${platform} suffix" % tool.cipd_package
    )
    api.upload.cipd_package(
        tool.cipd_package,
        api.path.abs_to_path(api.path.dirname(path)),
        [api.upload.FilePath(path)],
        {"git_revision": revision},
        repository=remote,
        install_mode=None,
        step_name="upload %s to cipd" % tool.name,
    )


def upload_to_gcs(api, tool, path):
    assert tool.gcs_path, "tool %s specifies a gcs_bucket but no gcs_path" % tool.name
    api.gsutil.upload(
        src=path,
        bucket=tool.gcs_bucket,
        dst=tool.gcs_path,
        link_name=tool.name,
        name="upload %s to %s" % (tool.name, tool.gcs_bucket),
    )


def GenTests(api):
    def test(name, tryjob=False):
        repo = "https://fuchsia.googlesource.com/integration"
        properties = InputProps(
            manifest="flower",
            remote=repo,
            tools=[
                InputProps.Tool(name="foo", cipd_package="tools/foo/${platform}"),
                InputProps.Tool(
                    name="bar",
                    cipd_package="tools/bar/${platform}",
                    gcs_bucket="bkt",
                    gcs_path="bar",
                ),
            ],
            fint_params_path="host-prebuilts.textproto",
        )
        ret = api.status_check.test(name) + api.properties(properties)
        if tryjob:
            ret += api.buildbucket.try_build(git_repo=repo)
        else:
            ret += api.buildbucket.ci_build(git_repo=repo)
        return ret

    yield test("ci")

    yield test("cq", tryjob=True)
