# Copyright 2022 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.

"""Sync CIPD package(s) into a Git repository."""

from PB.recipes.fuchsia.cipd_to_git_roller import InputProperties

DEPS = [
    "fuchsia/auto_roller",
    "fuchsia/buildbucket_util",
    "fuchsia/cipd_resolver",
    "fuchsia/git_checkout",
    "recipe_engine/cipd",
    "recipe_engine/file",
    "recipe_engine/json",
    "recipe_engine/path",
    "recipe_engine/properties",
    "recipe_engine/step",
]

PROPERTIES = InputProperties


def RunSteps(api, props):
    props.tag = props.tag or "version"
    props.ref = props.ref or "latest"

    # Note that we only support Git checkouts. Jiri checkouts are not expected
    # for binary Git repositories.
    checkout_dir = api.path.mkdtemp("checkout")
    api.git_checkout(props.remote, path=checkout_dir)

    with api.step.nest("fetch packages"):
        candidate_versions = api.cipd_resolver.resolve_common_tags(
            ref=props.ref,
            tag_name=props.tag,
            # Note: the ${platform} magic string is not supported yet.
            packages=[package.name for package in props.packages],
        )
        if not candidate_versions:
            raise api.step.StepFailure("Failed to resolve a tag to roll to.")

        version = candidate_versions[0]
        ensure_file = api.cipd.EnsureFile()
        for package in props.packages:
            # Wipe the subdirectory to avoid accumulating stale files from one
            # roll to the next.
            package_dir = checkout_dir.join(package.subdir)
            api.path.mock_add_paths(package_dir)
            if api.path.exists(package_dir):
                api.file.rmtree(
                    "wipe {subdir} for {package_name}".format(
                        subdir=package.subdir,
                        package_name=package.name,
                    ),
                    package_dir,
                )
            ensure_file.add_package(package.name, version, subdir=package.subdir)
        api.cipd.ensure(checkout_dir, ensure_file)

    commit_message = api.auto_roller.generate_package_roll_message(
        [package.name for package in props.packages],
        version,
        dry_run=props.roll_options.dry_run,
    )

    change = api.auto_roller.attempt_roll(
        props.roll_options,
        repo_dir=checkout_dir,
        commit_message=commit_message,
    )
    return api.auto_roller.raw_result(change)


def GenTests(api):
    def resolved_tags(tags):
        return api.step_data(
            "fetch packages.resolve common tags",
            api.json.output(tags),
        )

    default_props = api.properties(
        packages=[
            {
                "name": "fuchsia/foo/linux-amd64",
                "subdir": "prebuilt/foo/amd64",
            },
            {
                "name": "fuchsia/bar/linux-arm64",
                "subdir": "prebuilt/bar/arm64",
            },
        ],
        remote="https://fuchsia.googlesource.com/prebuilts",
        roll_options=api.auto_roller.Options(
            remote="https://fuchsia.googlesource.com/prebuilts",
        ),
    )

    yield api.buildbucket_util.test(
        "tag_resolution_failed", builder="prebuilts-roller", status="failure"
    ) + default_props + resolved_tags([])

    yield api.buildbucket_util.test(
        "roll", builder="prebuilts-roller"
    ) + api.auto_roller.success() + default_props + resolved_tags(["version:1"])
