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

"""Ensure the MILESTONE file in integration.git is up-to-date."""

from PB.recipes.fuchsia.release.milestone_roller import InputProperties


DEPS = [
    "fuchsia/auto_roller",
    "fuchsia/gerrit",
    "fuchsia/jiri",
    "fuchsia/release",
    "fuchsia/status_check",
    "recipe_engine/file",
    "recipe_engine/path",
    "recipe_engine/properties",
    "recipe_engine/python",
    "recipe_engine/step",
]

PROPERTIES = InputProperties
COMMIT_MESSAGE = """[roll] Roll MILESTONE from {current} to {target}"""


def RunSteps(api, props):
    with api.step.nest("checkout"):
        api.jiri.init()
        api.jiri.import_manifest(props.manifest, props.remote, name=props.project)
        api.jiri.update(run_hooks=False)

    project_dir = api.path["start_dir"].join(*props.project.split("/"))
    with api.step.nest("resolve target milestone") as presentation:
        branches = api.release.get_branches(repo_path=project_dir, remotes=True)
        if not branches:
            api.python.failing_step(
                "no release branches found",
                "%s does not have any release branches" % props.remote,
            )
        # The target milestone is always 1 ahead of the latest milestone branch.
        target_milestone = 1 + (
            max([api.release.get_milestone_from_branch(b) for b in branches])
        )

        current_milestone = api.release.get_major_number(repo_path=project_dir)
        if current_milestone == target_milestone:
            api.python.succeeding_step(
                "nothing to roll",
                "milestone up-to-date",
            )
            return api.auto_roller.nothing_to_roll()

        # If the target milestone isn't equal to or exactly 1 greater than the
        # current milestone, either the MILESTONE file and/or the latest
        # milestone branch are invalid. Raise an exception and do not roll.
        if current_milestone + 1 != target_milestone:
            api.python.failing_step(
                "invalid milestone numbers",
                "target milestone %d is not an increment of current milestone %d"
                % (target_milestone, current_milestone),
            )

    api.release.write_major_number(target_milestone, repo_path=project_dir)

    if props.milestone_branches_path:
        configured_branches = api.file.read_json(
            "read milestone branch config",
            project_dir.join(props.milestone_branches_path),
            test_data=["f1"],
        )
        # If the milestone branch config file doesn't already contain the
        # current milestone branch, append it to the file.
        current_milestone_branch = "f%d" % current_milestone
        if current_milestone_branch not in configured_branches:
            api.file.write_json(
                "write milestone branch config",
                project_dir.join(props.milestone_branches_path),
                configured_branches + ["f%d" % current_milestone],
            )
            api.step(
                "generate configs",
                [project_dir.join(props.config_generator_path)],
            )

    change = api.auto_roller.attempt_roll(
        api.gerrit.host_from_remote_url(props.remote),
        gerrit_project=props.project,
        repo_dir=project_dir,
        commit_message=COMMIT_MESSAGE.format(
            current=current_milestone, target=target_milestone
        ),
        cl_notify_option=props.cl_notify_option,
        create_unique_id=props.create_unique_change_id,
        dry_run=props.dry_run,
    )
    return api.auto_roller.raw_result(change)


def GenTests(api):
    default_props = api.properties(
        project="integration",
        manifest="minimal",
        remote="https://fuchsia.googlesource.com/integration",
        milestone_branches_path="config/milestone_branches.json",
        config_generator_path="config/generator.sh",
    )
    yield api.status_check.test("no_branches", status="failure") + default_props

    yield api.status_check.test("roll") + api.release.get_branches(
        ["releases/foo", "releases/f1", "releases/f2"],
        nesting="resolve target milestone",
    ) + api.release.get_major_number(
        2, nesting="resolve target milestone"
    ) + api.auto_roller.success() + default_props

    yield api.status_check.test("nothing_to_roll") + api.release.get_branches(
        ["releases/foo", "releases/f1"],
        nesting="resolve target milestone",
    ) + api.release.get_major_number(
        2, nesting="resolve target milestone"
    ) + default_props

    yield api.status_check.test(
        "invalid_milestone_numbers", status="failure"
    ) + api.release.get_branches(
        ["releases/foo", "releases/f1"],
        nesting="resolve target milestone",
    ) + api.release.get_major_number(
        5, nesting="resolve target milestone"
    ) + default_props
