# 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",
    "fuchsia/git_checkout",
    "recipe_engine/cipd",
    "recipe_engine/context",
    "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:
            package_dir = checkout_dir / package.subdir
            api.path.mock_add_paths(package_dir)
            if api.path.exists(package_dir):
                # Wipe the subdirectory to avoid accumulating stale files from
                # one roll to the next. Also unstage the deletions so they
                # cleanly resolve with the CIPD package files.
                with api.context(cwd=checkout_dir), api.step.nest(
                    f"reset {package.name} subdir"
                ):
                    api.git.rm(pathspec=package_dir, recursive=True)
                    api.git.restore(pathspec=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"])
