# 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 recipe_api, recipe_test_api

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

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

INLINE_PROPERTIES_PROTO = """
import "recipe_modules/pigweed/txt_roll/txt_entry.proto";

message InputProperties {
  // Text entries to update.
  repeated recipe_modules.pigweed.txt_roll.TxtEntry txt_entries = 1;

  string commit_divider = 2;
}
"""

PROPERTIES = InputProperties


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

    assert len(props.txt_entries) == 1
    txt_entry = props.txt_entries[0]

    rolls = api.txt_roll.update(checkout=checkout, txt_entry=txt_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,
        )


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

    def _url(x):
        assert ':' not in x
        return 'https://foo.googlesource.com/' + x

    def trigger(url, **kwargs):
        return api.checkout.ci_test_data(git_repo=_url(url), **kwargs)

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

    yield api.test(
        'success',
        properties(
            api.txt_roll.entry(path='foo.txt', remote=_url('foo')),
            commit_divider='--divider--',
        ),
        trigger('foo'),
        api.gitiles.log('foo.txt.log foo.txt', 'A'),
    )

    yield api.test(
        'backwards',
        properties(api.txt_roll.entry(path='foo.txt', remote=_url('foo'))),
        api.gitiles.log('foo.txt.log foo.txt', 'A', n=0),
    )
