# Copyright 2020 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.
"""Test of rolls of multiple repositories."""

DEPS = [
    'fuchsia/status_check',
    'pigweed/roll_util',
    'recipe_engine/path',
    'recipe_engine/step',
]


def RunSteps(api):
    # pylint: disable=unnecessary-lambda
    path = lambda name: api.path['start_dir'].join(name)

    rolls = [
        api.roll_util.Roll(
            project_name='abc',
            old_revision='1' * 40,
            new_revision='4' * 40,
            proj_dir=path('abc'),
            direction=api.roll_util.Direction.FORWARD,
        ),
        api.roll_util.Roll(
            project_name='xyz',
            old_revision='9' * 40,
            new_revision='c' * 40,
            proj_dir=path('xyz'),
            direction=api.roll_util.Direction.FORWARD,
        ),
        api.roll_util.Roll(
            project_name='def',
            old_revision='5' * 40,
            new_revision='8' * 40,
            proj_dir=path('def'),
            direction=api.roll_util.Direction.FORWARD,
        ),
    ]

    message = api.roll_util.message(*rolls)
    with api.step.nest('message') as pres:
        pres.logs['message'] = message


def GenTests(api):  # pylint: disable=invalid-name
    yield (
        api.status_check.test('single_commits')
        + api.roll_util.commit_data('abc', api.roll_util.commit('4' * 40))
        + api.roll_util.commit_data('def', api.roll_util.commit('8' * 40))
        + api.roll_util.commit_data('xyz', api.roll_util.commit('c' * 40))
    )

    yield (
        api.status_check.test('multiple_commits')
        + api.roll_util.commit_data(
            'abc',
            api.roll_util.commit('2' * 40),
            api.roll_util.commit('3' * 40),
            api.roll_util.commit('4' * 40),
        )
        + api.roll_util.commit_data(
            'def',
            api.roll_util.commit('6' * 40),
            api.roll_util.commit('7' * 40),
            api.roll_util.commit('8' * 40),
        )
        + api.roll_util.commit_data(
            'xyz',
            api.roll_util.commit('a' * 40),
            api.roll_util.commit('b' * 40),
            api.roll_util.commit('c' * 40),
        )
    )

    yield (
        api.status_check.test('mixed')
        + api.roll_util.properties(commit_divider='--divider--')
        + api.roll_util.commit_data('abc', api.roll_util.commit('4' * 40))
        + api.roll_util.commit_data(
            'def',
            api.roll_util.commit('6' * 40),
            api.roll_util.commit('8' * 40),
        )
        + api.roll_util.commit_data(
            'xyz',
            api.roll_util.commit('a' * 40),
            api.roll_util.commit('b' * 40),
            api.roll_util.commit('c' * 40),
        )
    )
