# 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 InputProperties

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 = InputProperties


def RunSteps(api, props):
    checkout = api.checkout.fuchsia_with_options(
        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 = InputProperties(
            manifest="flower",
            remote=repo,
            tools=[
                InputProperties.Tool(name="foo", cipd_package="tools/foo/${platform}"),
                InputProperties.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)
