# 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/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.test(status.lower(), status=status)
            + api.properties(run_tests=True)
            + api.subbuild.child_build_steps(builds=[build])
        )
