# Copyright 2020 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 triggering CQ+2 on changes which meet submitability criteria and have opted in via Auto-Submit+1."""

from PB.recipe_engine import result
from PB.go.chromium.org.luci.buildbucket.proto import common
from recipe_engine.recipe_api import Property

DEPS = [
    "fuchsia/gerrit",
    "fuchsia/status_check",
    "recipe_engine/buildbucket",
    "recipe_engine/cipd",
    "recipe_engine/context",
    "recipe_engine/json",
    "recipe_engine/file",
    "recipe_engine/path",
    "recipe_engine/platform",
    "recipe_engine/properties",
    "recipe_engine/raw_io",
    "recipe_engine/step",
    "recipe_engine/url",
]

PROPERTIES = {
    "auto_submit_label": Property(
        kind=str,
        help="Label to trigger auto-submission",
        default="Fuchsia-Auto-Submit",
    ),
    "gerrit_host": Property(
        kind=str,
        help="Gerrit host to run against.",
        default="fuchsia-review.googlesource.com",
    ),
    "dry_run": Property(kind=bool, help="", default=False),
}

change_query_test_data = [
    {
        "id": "myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9940",
        "project": "myProject",
        "branch": "master",
        "change_id": "I8473b95934b5732ac55d26311a706c9c2bde9940",
        "subject": 'Revert "Implementing Feature X"',
        "status": "NEW",
        "created": "2013-02-01 09:59:32.126000000",
        "updated": "2013-02-21 11:16:36.775000000",
        "_number": 3965,
        "owner": {"name": "John Doe"},
    }
]


def _get_change_url(host, change):
    return "https://%s/c/%s/+/%s" % (host, change["project"], change["_number"])


def get_eligible_changes(api, host, auto_submit_label):
    raw_query = (
        "is:submittable -is:wip -(label:Commit-Queue+1 OR label:Commit-Queue+2) "
        "label:{}+1"
    ).format(auto_submit_label)
    changes = api.gerrit.change_query(
        name="get changes for %s" % host,
        query_string=raw_query,
        host=host,
        test_data=api.json.test_api.output(change_query_test_data),
    ).json.output
    # API returns None if there is no search results instead of [].
    if not changes:
        return []
    eligible_changes = []
    for change in changes:
        with api.step.nest("get details for %s" % change["_number"]) as presentation:
            presentation.links["change"] = _get_change_url(host, change)
            other_changes_info = api.gerrit.changes_submitted_together(
                "find dependent changes",
                api.url.unquote(change["id"]),
                query_params=["NON_VISIBLE_CHANGES"],
                host=host,
            ).json.output
            if (
                len(other_changes_info["changes"]) > 1
                or other_changes_info.get("non_visible_changes", 0) != 0
            ):
                continue
            change_mergeability = api.gerrit.get_mergeable(
                "get mergeable", change_id=api.url.unquote(change["id"]), host=host,
            ).json.output
            if not change_mergeability["mergeable"]:
                continue
            eligible_changes.append(change)
    return eligible_changes


def set_commit_queue(api, host, change):
    labels = {"Commit-Queue": 2}
    with api.step.nest("%s" % change["_number"]) as presentation:
        api.gerrit.set_review(
            name="CQ",
            change_id=api.url.unquote(change["id"]),
            labels=labels,
            host=host,
            notify="NONE",
        )
        presentation.links["change"] = _get_change_url(host, change)


def raw_result(host, changes, dry_run):
    if changes:
        contents = [
            "Submitted the following CLs{}:".format(" (dry run)" if dry_run else "")
        ]
        contents.extend(_get_change_url(host, change) for change in changes)
    else:
        contents = ["No CLs to submit."]

    return result.RawResult(
        summary_markdown="\n".join(contents), status=common.SUCCESS,
    )


def RunSteps(api, gerrit_host, dry_run, auto_submit_label):
    with api.step.nest("get eligible") as presentation:
        changes = get_eligible_changes(api, gerrit_host, auto_submit_label)
        if not changes:
            presentation.step_text = "\nno eligible changes."

    if changes:
        with api.step.nest("set cq+2") as presentation:
            if dry_run:
                for change in [
                    _get_change_url(gerrit_host, change) for change in changes
                ]:
                    presentation.links[change] = change
            else:
                for change in changes:
                    set_commit_queue(api, gerrit_host, change)

    return raw_result(gerrit_host, changes, dry_run)


def GenTests(api):
    changes_submitted_together = {
        "changes": [
            {"id": "myProject~master~I8473b95934b5732ac55d26311a706c9c2bde9941",},
        ],
        "non_visible_changes": 1,
    }
    no_changes_submitted_together = {"changes": [], "non_visible_changes": 0}

    mergeable_test_data = {
        "mergeable": True,
    }
    unmergeable_test_data = {
        "mergeable": False,
    }
    yield (
        api.status_check.test("default")
        + api.step_data(
            "get eligible.get details for 3965.find dependent changes",
            api.json.output(no_changes_submitted_together),
        )
        + api.step_data(
            "get eligible.get details for 3965.get mergeable",
            api.json.output(mergeable_test_data),
        )
    )
    yield (
        api.status_check.test("no_changes")
        + api.step_data(
            "get eligible.get changes for fuchsia-review.googlesource.com",
            api.json.output(None),
        )
    )
    yield (
        api.status_check.test("changes_submitted_together")
        + api.step_data(
            "get eligible.get details for 3965.find dependent changes",
            api.json.output(changes_submitted_together),
        )
    )
    yield (
        api.status_check.test("unmergeable")
        + api.step_data(
            "get eligible.get details for 3965.find dependent changes",
            api.json.output(no_changes_submitted_together),
        )
        + api.step_data(
            "get eligible.get details for 3965.get mergeable",
            api.json.output(unmergeable_test_data),
        )
    )

    yield (
        api.status_check.test("dry_run")
        + api.step_data(
            "get eligible.get details for 3965.find dependent changes",
            api.json.output(no_changes_submitted_together),
        )
        + api.step_data(
            "get eligible.get details for 3965.get mergeable",
            api.json.output(mergeable_test_data),
        )
        + api.properties(dry_run=True)
    )
