# 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.copy_roll.tests.full import InputProperties

DEPS = [
    'fuchsia/roll_commit_message',
    'pigweed/checkout',
    'pigweed/copy_roll',
    'recipe_engine/file',
    'recipe_engine/properties',
    'recipe_engine/step',
]

INLINE_PROPERTIES_PROTO = """
import "recipe_modules/pigweed/copy_roll/copy_entry.proto";

message InputProperties {
  // Text entries to update.
  repeated recipe_modules.pigweed.copy_roll.CopyEntry copy_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()

    rolls = []
    for entry in props.copy_entries:
        rolls.extend(api.copy_roll.update(checkout=checkout, copy_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 _url(x):
        assert ':' not in x
        return 'https://foo.googlesource.com/' + x

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

    yield api.test(
        'success',
        properties(
            api.copy_roll.entry(
                remote=_url('foo'),
                source='source',
                dest='dest',
            ),
            commit_divider='--divider--',
        ),
        api.step_data('dest.read destination dest', api.file.read_text('old')),
        api.step_data('dest.read source source', api.file.read_text('new')),
    )

    yield api.test(
        'long',
        properties(
            api.copy_roll.entry(
                remote=_url('foo'),
                source='source',
                dest='dest',
            ),
            commit_divider='--divider--',
        ),
        api.step_data(
            'dest.read destination dest',
            api.file.read_text('old' * 30),
        ),
        api.step_data(
            'dest.read source source', api.file.read_text('new' * 31)
        ),
    )

    yield api.test(
        'two',
        properties(
            api.copy_roll.entry(
                remote=_url('foo'),
                source='source1',
                dest='dest1',
            ),
            api.copy_roll.entry(
                remote=_url('bar'),
                source='source2',
                dest='dest2',
            ),
        ),
        api.step_data(
            'dest1.read destination dest1',
            api.file.read_text('old1'),
        ),
        api.step_data('dest1.read source source1', api.file.read_text('new1')),
        api.step_data(
            'dest2.read destination dest2',
            api.file.read_text('old2'),
        ),
        api.step_data('dest2.read source source2', api.file.read_text('new2')),
    )

    yield api.test(
        'samesies',
        properties(
            api.copy_roll.entry(
                remote=_url('foo'),
                source='source',
                dest='dest',
            ),
        ),
        api.step_data(
            'dest.read destination dest',
            api.file.read_text('samesies'),
        ),
        api.step_data(
            'dest.read source source', api.file.read_text('samesies')
        ),
    )

    yield api.test(
        'executable_difference',
        properties(
            api.copy_roll.entry(
                remote=_url('foo'),
                source='source',
                dest='dest',
            ),
        ),
        api.step_data(
            'dest.read destination dest',
            api.file.read_text('samesies'),
        ),
        api.step_data(
            'dest.read source source', api.file.read_text('samesies')
        ),
        api.step_data(
            'dest.check executable destination dest',
            api.file.is_executable(False),
        ),
        api.step_data(
            'dest.check executable source source',
            api.file.is_executable(True),
        ),
    )
