# Copyright 2025 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.
"""Full test of raw_result module."""

from __future__ import annotations

from collections.abc import Iterator

from recipe_engine import post_process, recipe_api, recipe_test_api

from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb
from PB.recipe_engine import result as result_pb
from PB.recipe_modules.pigweed.raw_result.tests.full import InputProperties

from RECIPE_MODULES.pigweed.raw_result import api as raw_result_api

DEPS = [
    'pigweed/raw_result',
    'recipe_engine/buildbucket',
    'recipe_engine/properties',
    'recipe_engine/step',
]

INLINE_PROPERTIES_PROTO = """
message InputProperties {
  string result = 1;

  bool bisector = 2;
}
"""

PROPERTIES = InputProperties


@raw_result_api.wrap_run_steps
def RunSteps(
    api: recipe_api.RecipeScriptApi,
    props: InputProperties,
) -> result_pb.RawResult | None:
    if props.result == 'step failure':
        raise api.step.StepFailure(props.result)

    if props.result == 'infra failure':
        raise api.step.InfraFailure(props.result)

    if props.result == 'exception':
        raise Exception(props.result)

    if props.result == 'raw success':
        return result_pb.RawResult(
            summary_markdown=props.result,
            status=common_pb.SUCCESS,
        )

    if props.result == 'raw failure':
        return result_pb.RawResult(
            summary_markdown=props.result,
            status=common_pb.FAILURE,
        )

    if props.result == 'LUCI CV no longer needs this Tryjob':
        raise api.step.StepFailure('LUCI CV no longer needs this Tryjob')

    if props.result == 'none':
        return None

    api.step.empty('should never get here')  # pragma: no cover


def GenTests(api) -> Iterator[recipe_test_api.TestData]:
    def test(name, *args, **kwargs) -> recipe_test_api.TestData:
        bisector = False
        result = name
        if 'bisector' in name:
            bisector = True
            result = name.replace('bisector', '').replace('  ', ' ').strip()
        return api.test(
            name,
            api.buildbucket.ci_build(
                experiments=kwargs.pop('experiments', ()),
            ),
            api.post_process(post_process.DoesNotRun, 'should never get here'),
            api.properties(result=result),
            api.properties(**{'$fuchsia/bisector': {'enabled': bisector}}),
            *args,
            **kwargs,
        )

    yield test(
        'step failure',
        experiments=('pigweed.disable_rbe',),
        status='FAILURE',
    )
    yield test('infra failure', status='INFRA_FAILURE')
    yield test('exception', api.expect_exception('Exception'))
    yield test('raw success', status='SUCCESS')
    yield test('raw failure', status='FAILURE')
    yield test('LUCI CV no longer needs this Tryjob', status='FAILURE')
    yield test('none', status='SUCCESS')

    yield test('step failure bisector', status='FAILURE')
    yield test('infra failure bisector', status='INFRA_FAILURE')
    yield test(
        'exception bisector',
        status='INFRA_FAILURE',
        experiments=('luci.non_production',),
    )
    yield test('raw success bisector', status='SUCCESS')
    yield test(
        'raw failure bisector',
        experiments=('pigweed.disable_github',),
        status='FAILURE',
    )
    yield test(
        'LUCI CV no longer needs this Tryjob bisector', status='CANCELED'
    )
    yield test('none bisector', status='SUCCESS')
