# Copyright 2024 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.run_script_roll.tests.full import InputProperties

DEPS = [
    'fuchsia/roll_commit_message',
    'pigweed/checkout',
    'pigweed/run_script_roll',
    'recipe_engine/json',
    'recipe_engine/properties',
    'recipe_engine/step',
]

INLINE_PROPERTIES_PROTO = """
import "recipe_modules/pigweed/run_script_roll/run_script_entry.proto";

message InputProperties {
  // Text entries to update.
  repeated recipe_modules.pigweed.run_script_roll.RunScriptEntry run_script_entries = 1;
}
"""

PROPERTIES = InputProperties


def RunSteps(  # pylint: disable=invalid-name
    api: recipe_api.RecipeScriptApi,
    props: InputProperties,
):
    checkout = api.checkout.fake_context()

    rolls = []
    for entry in props.run_script_entries:
        rolls.extend(
            api.run_script_roll.run(
                checkout=checkout,
                run_script_entry=entry,
            ),
        )

    if rolls:
        pres = api.step.empty('commit message').presentation
        pres.step_summary_text = api.roll_commit_message.format(
            *rolls,
            roll_prefix='roll:',
            send_comment=True,
        )
        for roll in rolls:
            pres.properties[roll.short_name()] = roll.output_property()


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

    def properties(*run_script_entries, **kwargs):
        props = InputProperties(**kwargs)
        props.run_script_entries.extend(run_script_entries)
        return api.properties(props)

    yield api.test(
        'success',
        properties(api.run_script_roll.entry('update.sh')),
        api.post_check(post_process.MustRun, 'commit message'),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'two',
        properties(
            api.run_script_roll.entry('one.sh'),
            api.run_script_roll.entry('two.sh'),
        ),
        api.post_check(post_process.MustRun, 'commit message'),
        api.post_process(post_process.DropExpectation),
    )

    yield api.test(
        'noop',
        properties(api.run_script_roll.entry('update.sh')),
        api.step_data(
            'update.sh.run',
            stdout=api.json.output({}),
        ),
        api.post_check(post_process.DoesNotRun, 'commit message'),
        api.post_process(post_process.DropExpectation),
    )
