# 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.
"""Recipe for rolling submodule"""

from recipe_engine import post_process

from PB.recipes.fuchsia.submodule_update import InputProperties
from PB.go.chromium.org.luci.buildbucket.proto import common

DEPS = [
    "fuchsia/auto_roller",
    "fuchsia/buildbucket_util",
    "fuchsia/checkout",
    "fuchsia/git",
    "fuchsia/git_checkout",
    "fuchsia/jiri",
    "fuchsia/submodule_update",
    "recipe_engine/buildbucket",
    "recipe_engine/context",
    "recipe_engine/json",
    "recipe_engine/path",
    "recipe_engine/properties",
    "recipe_engine/raw_io",
    "recipe_engine/step",
]

PROPERTIES = InputProperties


def RunSteps(api, props):
    checkout = api.checkout.fuchsia_with_options(
        project=props.project,
        manifest=props.manifest,
        remote=props.remote,
        # Skip for faster checkout.
        fetch_packages=False,
        # This recipe is intended to do the work of synchronizing submodules and jiri
        # state for users' local checkout, so skip the checkout logic to synchronize
        # the two on the fly. The diff will be reconciled further in the submodule
        # update tool.
        submodule_update=False,
    )

    revision = str(api.buildbucket.build.input.gitiles_commit.id)
    branch = str(api.buildbucket.build.input.gitiles_commit.ref)

    with api.context(cwd=checkout.root_dir):
        jiri_projects_path = api.path.mkstemp("jiri-projects-json")
        api.jiri.project(out=jiri_projects_path)
        # We are checking in cipd files to the superproject, so renaming the
        # files with basename "cipd". Snapshot (named "cipd") here is not currently used.
        snapshot_files = api.jiri.snapshot(api.path.cleanup_dir / "cipd", cipd=True)
        with api.context(checkout.root_dir / "integration"):
            author_name = api.git.get_author_name(commit=revision)
            author_email = api.git.get_author_email(commit=revision)
            message = api.git.get_commit_message(
                commit=revision, step_name="get commit message"
            )

    with api.step.nest("checkout super project"):
        superproject_path, _ = api.git_checkout(
            props.superproject,
            submodules=False,
            revision=branch,
        )

    # Print JSON inputs as a temporary debugging helper
    host = api.buildbucket.build.input.gitiles_commit.host
    project = api.buildbucket.build.input.gitiles_commit.project
    inputs = {
        "superproject_path": superproject_path,
        "jiri_projects_path": jiri_projects_path,
        "snapshot_paths": snapshot_files,
        "current_revision": revision,
        "host": host,
        "project": project,
        "branch": branch,
        "commit_author_name": author_name,
        "commit_author_email": author_email,
        "commit_message": message,
    }
    api.step.empty("print json inputs", log_text=api.json.dumps(inputs, indent=2))

    # Calls the submodule_update tool integration update.
    # TODO(yupingz): returns a json file with submodules needed for updates.
    api.submodule_update.integration_update(
        "integration update", inputs, no_commit=True
    )

    commit_message = write_commit_message(message)

    with api.context(cwd=superproject_path):
        api.git.status()
        props.roll_options.upstream_ref = props.roll_options.upstream_ref or branch
        change = api.auto_roller.attempt_roll(
            props.roll_options,
            repo_dir=superproject_path,
            commit_message=commit_message,
            # TODO(yupingz): for single commit, override author with original
            # change's author.
            author_override=None,
            raise_on_failure=False,
        )
        return api.auto_roller.raw_result(change)


def write_commit_message(message):
    # Drop Change-Id from original commit message.
    commit_message = message.split("\nChange-Id:")[0]

    # Differentiate integration roll from superproject roll.
    if commit_message.startswith("[roll]"):
        commit_message = commit_message.replace("[roll]", "[superproject]", 1)
    return commit_message


def GenTests(api):
    def properties(dry_run=False):
        props = {
            "manifest": "flower",
            "remote": "https://fuchsia.googlesource.com/integration",
            "superproject": "https://fuchsia.googlesource.com/superproject",
            "roll_options": api.auto_roller.Options(
                dry_run=dry_run,
                force_submit=True,
                remote="https://fuchsia.googlesource.com/superproject",
            ),
        }
        return api.properties(**props)

    message_data = api.step_data(
        "get commit message", api.raw_io.stream_output_text("[roll] roll change")
    )

    yield (
        api.buildbucket_util.test("basic", repo="fuchsia") + properties() + message_data
    )

    yield (api.buildbucket_util.test("dry_run") + properties(dry_run=True))
