# Copyright 2020 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 updating CIPD refs based on the contents of Fuchsia integration."""

from PB.recipes.fuchsia.cipd_integration_tagger import InputProperties

DEPS = [
    "fuchsia/checkout",
    "fuchsia/jiri",
    "recipe_engine/cipd",
    "recipe_engine/context",
    "recipe_engine/properties",
]

PROPERTIES = InputProperties


def RunSteps(api, props):
    props.ref = props.ref or "integration"

    # TODO(nmulcahey): Get the manifest structure without checkout out all of
    # Fuchsia. Jiri doesn't currently expose this as an explicit option, it
    # may be possible to do it by running int + import + using remote
    # manifests. But at least the packages and run-hooks can be skipped.
    checkout = api.checkout.fuchsia_with_options(
        manifest=props.manifest,
        remote=props.remote,
        fetch_packages=False,
    )

    with api.context(cwd=checkout.root_dir):
        package_data = api.jiri.package(props.packages).json.output

        for package in package_data:
            platforms = package.get("platforms", None)
            if not platforms:
                api.cipd.set_ref(
                    package_name=package["name"],
                    version=package["version"],
                    refs=[props.ref],
                )
                continue
            for platform in platforms:
                package_name = package["name"].replace("${platform}", platform)
                api.cipd.set_ref(
                    package_name=package_name,
                    version=package["version"],
                    refs=[props.ref],
                )


def GenTests(api):
    package_test_data = [
        {
            "name": "ref-set/${platform}",
            "platforms": ["linux-x64", "mac-x64"],
            "version": "0123456789ABCDEF",
        },
        {"name": "ref-set/linux-arm64", "version": "0123456789ABCDEF,1"},
        {
            "name": "ref-unset/${platform}",
            "platforms": ["linux-x64"],
            "version": "DEADBEAF",
        },
    ]

    properties = {
        "packages": ["ref-set/${platform}", "ref-unset/${platform}"],
        "remote": "https://fuchsia.googlesource.com/integration",
        "manifest": "flower",
    }

    yield (
        api.test("default")
        + api.properties(**properties)
        + api.step_data("jiri package", api.jiri.package(package_test_data))
    )
