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

from PB.recipes.fuchsia.roller_config_deployer import InputProperties

DEPS = [
    "fuchsia/auto_roller",
    "fuchsia/buildbucket_util",
    "fuchsia/git_checkout",
    "fuchsia/roller_configurator",
    "recipe_engine/buildbucket",
    "recipe_engine/file",
    "recipe_engine/path",
    "recipe_engine/properties",
    "recipe_engine/step",
]

PROPERTIES = InputProperties


def RunSteps(api, props):
    # Checkout triggering repository
    host = api.buildbucket.build.input.gitiles_commit.host
    project = api.buildbucket.build.input.gitiles_commit.project
    remote = "https://" + host + "/" + project
    triggering_repo_dir, _ = api.git_checkout(remote)

    # Checkout integration.git
    integration_checkout_dir, _ = api.git_checkout(
        props.integration_remote, ignore_build_input=True
    )

    # Get output file path from repos.json
    repos_json_path = (
        integration_checkout_dir / "infra/config/common/roller_configs/repos.json"
    )
    repos_json_file = api.file.read_json("read repos list", repos_json_path)
    relative_output_path = ""
    if remote in repos_json_file:
        relative_output_path = repos_json_file[remote]
    else:
        relative_output_path = api.path.join(
            host, project.replace("/", "-"), "rollers.json"
        )
        repos_json_file[remote] = relative_output_path
        api.file.write_json("write repos list", repos_json_path, repos_json_file)
    # Run roller-configurator resolve to get JSON output
    absolute_output_path = (
        integration_checkout_dir
        / "infra/config/common/roller_configs"
        / relative_output_path
    )
    path_to_roller_config = triggering_repo_dir / "rollers.textproto"
    api.roller_configurator.resolve(absolute_output_path, path_to_roller_config)

    # Run gen.sh to update the list of builders
    api.step("regen starlark", [integration_checkout_dir / "infra/config/gen.sh"])

    # Push changes to integration.git
    gerrit_change = api.auto_roller.attempt_roll(
        props.roll_options,
        repo_dir=integration_checkout_dir,
        commit_message=f"Deploy roller configs for {remote}",
    )
    return api.auto_roller.raw_result(gerrit_change)


def GenTests(api):
    input_properties = InputProperties(
        integration_remote="https://fuchsia.googlesource.com/integration",
        roll_options=api.auto_roller.Options(
            remote="https://fuchsia.googlesource.com/integration"
        ),
    )
    yield api.buildbucket_util.test(
        "path_in_repos",
        project="fuchsia",
        git_repo="https://fuchsia.googlesource.com/fuchsia",
    ) + api.properties(input_properties) + api.auto_roller.success() + api.step_data(
        "read repos list",
        api.file.read_json({"https://fuchsia.googlesource.com/fuchsia": "/fuchsia"}),
    )

    yield api.test("path_not_in_repos") + api.buildbucket.ci_build(
        project="fuchsia", git_repo="https://fuchsia.googlesource.com/fuchsia"
    ) + api.properties(input_properties) + api.auto_roller.success() + api.step_data(
        "read repos list", api.file.read_json({})
    )
