# Copyright 2021 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 CTS artifacts.

TODO(atyfto): Consider generalizing this recipe with prebuilt_host_tool.py.
"""

from PB.recipes.fuchsia.cts_artifacts import InputProperties

PYTHON_VERSION_COMPATIBILITY = "PY3"

DEPS = [
    "fuchsia/build",
    "fuchsia/buildbucket_util",
    "fuchsia/checkout",
    "fuchsia/cipd_util",
    "fuchsia/release",
    "recipe_engine/buildbucket",
    "recipe_engine/properties",
]

PROPERTIES = InputProperties


def RunSteps(api, props):
    checkout = api.checkout.fuchsia_with_options(
        manifest=props.manifest, remote=props.remote
    )

    cipd_package_ref = "latest"
    sdk_id = None
    ref = api.buildbucket.build.input.gitiles_commit.ref
    if ref.startswith("refs/heads/releases/"):
        integration_root = checkout.root_dir.join("integration")
        release_version = api.release.get_current_release_version(integration_root)
        sdk_id = str(release_version).replace("releases/", "")
        cipd_package_ref = ref[len("refs/heads/releases/") :]

    # TODO(87346): This allows us to soft-transition the canary CTS roller from
    # the 'latest' ref to the 'canary' ref.
    cipd_package_refs = (cipd_package_ref,)
    if cipd_package_ref == "canary":
        cipd_package_refs = ("canary", "latest")

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

    if api.buildbucket_util.is_tryjob or not props.cipd_package:
        return

    revision = str(api.buildbucket.build.input.gitiles_commit.id)
    assert revision
    api.cipd_util.upload_package(
        props.cipd_package,
        build_results.build_dir,
        pkg_paths=build_results.cts_artifacts,
        search_tag={"git_revision": revision},
        refs=cipd_package_refs,
        repository=props.remote,
        step_name="upload cts artifacts to cipd",
    )


def GenTests(api):
    def properties(**kwargs):
        props = {
            "manifest": "flower",
            "remote": "https://fuchsia.googlesource.com/integration",
            "cipd_package": "fuchsia/cts/{platform}",
            "fint_params_path": "cts-artifacts.textproto",
        }
        props.update(kwargs)
        return api.properties(InputProperties(**props))

    yield api.buildbucket_util.test(
        "milestone",
        repo="fuchsia",
        git_ref="refs/heads/releases/f5",
    ) + properties() + api.release.ref_to_release_version("releases/5.20210102.3.1")
    yield api.buildbucket_util.test(
        "canary",
        repo="fuchsia",
        git_ref="refs/heads/releases/canary",
    ) + properties() + api.release.ref_to_release_version("releases/5.20210102.3.1")

    yield api.buildbucket_util.test("ci", repo="fuchsia") + properties()
    yield api.buildbucket_util.test("cq", tryjob=True, repo="fuchsia") + properties()
