# Copyright 2026 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.

from __future__ import annotations

from collections.abc import Iterator

from recipe_engine import post_process, recipe_api, recipe_test_api

from PB.recipe_modules.pigweed.merge_roll.tests.full import InputProperties

DEPS = [
    'fuchsia/gitiles',
    'fuchsia/roll_commit_message',
    'pigweed/checkout',
    'pigweed/merge_roll',
    'recipe_engine/properties',
    'recipe_engine/step',
]

INLINE_PROPERTIES_PROTO = """
import "recipe_modules/pigweed/merge_roll/merge.proto";

message InputProperties {
  recipe_modules.pigweed.merge_roll.MergeEntry merge = 1;
}
"""

PROPERTIES = InputProperties


def RunSteps(
    api: recipe_api.RecipeScriptApi,
    props: InputProperties,
):
    checkout = api.checkout.fake_context()

    rolls = api.merge_roll.merge(checkout, props.merge)

    if not rolls:
        with api.step.nest('nothing to roll, exiting'):
            return

    message = api.step.empty('commit message').presentation
    message.step_summary_text = api.roll_commit_message.format(
        *rolls,
        roll_prefix='roll:',
        send_comment=True,
    )


def GenTests(api) -> Iterator[recipe_test_api.TestData]:
    """Create tests."""

    def properties(*merges, **kwargs):
        props = InputProperties(**kwargs)
        assert len(merges) == 1
        props.merge.CopyFrom(merges[0])
        return api.properties(props)

    yield api.test(
        'success',
        properties(api.merge_roll.entry('staging')),
        api.gitiles.log('staging.log staging', 'A'),
        api.post_check(post_process.MustRun, 'staging.git merge'),
        api.post_check(post_process.MustRun, 'commit message'),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'backwards_roll',
        properties(api.merge_roll.entry('staging')),
        api.gitiles.log('staging.log staging', 'A', n=0),
        api.post_check(post_process.MustRun, 'staging.output property'),
        api.post_check(post_process.MustRun, 'nothing to roll, exiting'),
        api.post_check(post_process.DoesNotRun, 'commit message'),
        api.post_process(post_process.DropExpectation),
    )
