# 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 = f'{api.buildbucket.build.builder.builder}-subbuild'

    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 = f'[build]({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])
        )
