# 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 toolchain buildbucket builds."""

from PB.go.chromium.org.luci.buildbucket.proto import (
    builds_service as builds_service_pb2,
)
from PB.recipes.fuchsia.contrib.toolchain_trigger import InputProperties

DEPS = [
    "fuchsia/buildbucket_util",
    "recipe_engine/buildbucket",
    "recipe_engine/properties",
    "recipe_engine/scheduler",
    "recipe_engine/step",
    "recipe_engine/swarming",
]

PROPERTIES = InputProperties


def RunSteps(api, props):
    # Trigger the builders.
    builds = api.buildbucket.schedule(
        [
            api.buildbucket.schedule_request(
                builder,
                bucket=props.bucket,
                swarming_parent_run_id=api.swarming.task_id,
            )
            for builder in props.builders
        ]
        + [
            api.buildbucket.schedule_request(
                builder,
                bucket=props.bucket,
            )
            for builder in props.nonblocking_builders
        ],
        step_name="schedule builds",
    )
    build_ids = [b.id for b in builds if b.builder.builder in props.builders]
    build_dict = api.buildbucket.collect_builds(
        build_ids,
        interval=props.interval,
        timeout=props.timeout,
        step_name="collect builds",
    )
    build_results = [build_dict[id] for id in build_ids]
    api.buildbucket_util.display_builds(
        step_name="display builds", builds=build_results, raise_on_failure=True
    )

    properties = {}
    if props.enforce_output:
        revision = retrieve_revision(api, build_results)
        properties = {"version": "git_revision:" + revision}

    # Trigger next stage builders
    api.scheduler.emit_trigger(
        api.scheduler.BuildbucketTrigger(properties=properties),
        project=api.buildbucket.build.builder.project,
        jobs=props.triggers,
    )


def retrieve_revision(api, results):
    revision = None
    for result in results:
        output = result.output.properties
        if "git_revision" not in output:
            raise api.step.StepFailure("revision not found in build")
        output_revision = output["git_revision"]
        if revision is None:
            revision = output_revision
        elif revision != output_revision:
            raise api.step.StepFailure(
                "revisions not unified: %s:%s" % (revision, output_revision)
            )
    return revision


def GenTests(api):
    default_properties = api.properties(
        builders=["clang-linux-x64", "clang-mac-x64"],
        nonblocking_builders=["clang-windows-x64"],
        triggers=["clang-trigger"],
        enforce_output=True,
    )

    test_build = api.buildbucket.ci_build_message(
        status="SUCCESS", builder="clang-linux-x64"
    )
    test_build.output.properties["git_revision"] = "a" * 40
    mock_schedule_data = api.buildbucket.simulated_schedule_output(
        step_name="schedule builds",
        batch_response=builds_service_pb2.BatchResponse(
            responses=[
                dict(
                    schedule_build=dict(
                        id=test_build.id,
                        builder=dict(builder=test_build.builder.builder),
                    )
                )
            ],
        ),
    )
    mock_collect_data = api.buildbucket.simulated_collect_output(
        step_name="collect builds",
        builds=[test_build],
    )

    yield (
        api.buildbucket_util.test("default", repo="example", revision="a" * 40)
    ) + default_properties + mock_schedule_data + mock_collect_data

    test_build_mismatch = api.buildbucket.ci_build_message(
        build_id=test_build.id + 1, status="SUCCESS", builder="clang-linux-x64"
    )
    test_build_mismatch.output.properties["git_revision"] = "b" * 40
    mock_schedule_data_mismatch = api.buildbucket.simulated_schedule_output(
        step_name="schedule builds",
        batch_response=builds_service_pb2.BatchResponse(
            responses=[
                dict(
                    schedule_build=dict(
                        id=test_build.id,
                        builder=dict(builder=test_build.builder.builder),
                    )
                ),
                dict(
                    schedule_build=dict(
                        id=test_build_mismatch.id,
                        builder=dict(builder=test_build_mismatch.builder.builder),
                    )
                ),
            ],
        ),
    )
    mock_collect_data_mismatch = api.buildbucket.simulated_collect_output(
        step_name="collect builds",
        builds=[test_build, test_build_mismatch],
    )

    yield (
        api.buildbucket_util.test(
            "mismatch", repo="example", revision="a" * 40, status="failure"
        )
    ) + default_properties + mock_schedule_data_mismatch + mock_collect_data_mismatch

    test_build_no_output = api.buildbucket.ci_build_message(
        status="SUCCESS", builder="clang-linux-x64"
    )
    mock_schedule_data_no_output = api.buildbucket.simulated_schedule_output(
        step_name="schedule builds",
        batch_response=builds_service_pb2.BatchResponse(
            responses=[
                dict(
                    schedule_build=dict(
                        id=test_build_no_output.id,
                        builder=dict(builder=test_build.builder.builder),
                    )
                )
            ],
        ),
    )
    mock_collect_data_no_output = api.buildbucket.simulated_collect_output(
        step_name="collect builds",
        builds=[test_build_no_output],
    )

    no_output_properties = api.properties(
        builders=["clang-linux-x64", "clang-mac-x64"],
        triggers=["clang-trigger"],
        enforce_output=False,
    )
    yield (
        api.buildbucket_util.test("no_output", repo="example", revision="a" * 40)
    ) + no_output_properties + mock_schedule_data_no_output + mock_collect_data_no_output

    yield (
        api.buildbucket_util.test(
            "no_output_with_enforce",
            repo="example",
            revision="a" * 40,
            status="failure",
        )
    ) + default_properties + mock_schedule_data_no_output + mock_collect_data_no_output

    test_build_failure = api.buildbucket.ci_build_message(
        status="FAILURE", builder="clang-linux-x64"
    )
    mock_failure_schedule_data = api.buildbucket.simulated_schedule_output(
        step_name="schedule builds",
        batch_response=builds_service_pb2.BatchResponse(
            responses=[
                dict(
                    schedule_build=dict(
                        id=test_build_failure.id,
                        builder=dict(builder=test_build_failure.builder.builder),
                    )
                )
            ],
        ),
    )
    mock_failure_collect_data = api.buildbucket.simulated_collect_output(
        step_name="collect builds",
        builds=[test_build_failure],
    )

    yield (
        api.buildbucket_util.test(
            "default_fail", repo="example", revision="a" * 40, status="failure"
        )
    ) + default_properties + mock_failure_schedule_data + mock_failure_collect_data
