# 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

PYTHON_VERSION_COMPATIBILITY = "PY3"

DEPS = [
    "fuchsia/auto_roller",
    "fuchsia/buildbucket_util",
    "fuchsia/checkout",
    "fuchsia/gerrit",
    "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 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 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,
    )

    revision = str(api.buildbucket.build.input.gitiles_commit.id)
    branch = str(api.buildbucket.build.input.gitiles_commit.ref)
    api.step("print commit id", ["echo", revision])
    last_successful_build = api.buildbucket_util.last_build(status=common.SUCCESS)
    prev_revision = ""
    if last_successful_build:
        prev_revision = str(last_successful_build.input.gitiles_commit.id)
        api.step("print previous commit id", ["echo", prev_revision])

    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"].join("cipd"), cipd=True)
        with api.context(checkout.root_dir.join("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,
        "previous_revision": prev_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", api.json.input(inputs), no_commit=True
    )

    commit_message = write_commit_message(message)

    with api.context(cwd=superproject_path):
        api.git.status()
        change = api.auto_roller.attempt_roll(
            api.gerrit.host_from_remote_url(props.superproject),
            gerrit_project=api.gerrit.project_from_remote_url(props.superproject),
            repo_dir=superproject_path,
            commit_message=commit_message,
            # TODO(yupingz): for single commit, override author with original
            # change's author.
            author_override=None,
            dry_run=props.dry_run,
            # Rolling a manifest change that is already tested, no need to CQ.
            force_submit=True,
            raise_on_failure=False,
            # TODO(yupingz): Add roller owners.
            roller_owners=None,
            # TODO(yupingz): Add upstream_ref to support other branches.
            # Default: MAIN
        )
        return api.auto_roller.raw_result(change)


def GenTests(api):
    def properties(**kwargs):
        props = {
            "manifest": "flower",
            "remote": "https://fuchsia.googlesource.com/integration",
            "superproject": "https://fuchsia.googlesource.com/superproject",
            "dry_run": False,
        }
        props.update(kwargs)
        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()
        + api.post_process(post_process.MustRun, "print commit id")
        + api.buildbucket.simulated_search_results([api.buildbucket.ci_build_message()])
        + message_data
    )

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