# Copyright 2021 The Pigweed Authors
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may not
# use this file except in compliance with the License. You may obtain a copy of
# the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under
# the License.
"""Recipe for testing Pigweed with multiple swarming tasks."""

from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
from PB.recipes.pigweed.pigweed import Pigweed

DEPS = [
    'fuchsia/buildbucket_util',
    'fuchsia/status_check',
    'fuchsia/subbuild',
    'pigweed/build',
    'recipe_engine/buildbucket',
    'recipe_engine/properties',
    'recipe_engine/step',
]

PROPERTIES = Pigweed


def RunSteps(api, props):
    with api.step.nest('build') as pres:
        child_build = run_build_steps(api, pres)
        build_digest = api.subbuild.get_property(
            child_build, api.build.CAS_DIGEST_PROPERTY_NAME,
        )

    if props.run_tests:
        with api.step.nest('test') as pres:
            run_test_steps(api, pres)


def run_build_steps(api, presentation):
    builder_name = '{}-subbuild'.format(api.buildbucket.build.builder.builder)

    extra_props = {'parent_id': api.buildbucket_util.id}

    builds = api.subbuild.launch(
        [builder_name], presentation, extra_properties=extra_props,
    )

    build_id = builds[builder_name].build_id
    build_url = builds[builder_name].url
    builds = api.subbuild.collect([build_id])
    output_build = builds[build_id].build_proto

    if output_build.status != common_pb2.SUCCESS:
        presentation.properties['failed_to_build'] = True
        if output_build.status == common_pb2.INFRA_FAILURE:
            exception_type = api.step.InfraFailure
            description = 'raised infra failure'
        else:
            exception_type = api.step.StepFailure
            description = 'failed'

        # Copy the child summary markdown into the parent summary markdown to
        # better propagate error messages. If the child summary is multiple
        # lines, start it on a new line.
        subbuild_summary = output_build.summary_markdown.strip()
        summary = '[build](%s) %s' % (build_url, description)
        if subbuild_summary:
            summary += ':'
            # If the subbuild summary is already multiple lines, start it on a
            # new line. If it's one line, the final summary should also be one
            # line.
            summary += '\n\n' if '\n' in subbuild_summary else ' '
            summary += subbuild_summary
        raise exception_type(summary)

    return output_build


def run_test_steps(api, presentation):
    pass


def GenTests(api):
    for status in ('success', 'failure', 'infra_failure'):
        build = api.subbuild.ci_build_message(
            builder='-subbuild',
            input_props={"parent_id": "123123"},
            output_props={'cas_build_digest': '123123/12'},
            status=status.upper(),
        )
        build.summary_markdown = status

        yield (
            api.status_check.test(status, status=status)
            + api.properties(run_tests=True)
            + api.subbuild.child_build_steps(builds=[build])
        )
