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

from recipe_engine import post_process, recipe_test_api


class RollUtilTestApi(recipe_test_api.RecipeTestApi):
    def commit(self, hash, message=None, author='author@example.com'):
        if not message:
            message = """
module: Short commit summary

Longer commit details.

Bug: 123
Change-Id: I{hash}
Reviewed-On: https://pigweed-review.googlesource.com/c/project/+/{hash:.5}
            """.strip().format(
                hash=hash
            )
        return '\n'.join((hash, author, message))

    def commit_data(self, name, *commits, **kwargs):
        prefix = kwargs.pop('prefix', '')
        assert not kwargs
        assert isinstance(name, str)
        return self.step_data(
            '{}{}.git log'.format(prefix, name),
            stdout=self.m.raw_io.output('\0'.join(commits)),
        )

    def cancelled(self):
        return self.post_process(post_process.MustRunRE, '.*cancelling roll.*')

    def not_cancelled(self):
        return self.post_process(
            post_process.DoesNotRunRE, '.*cancelling roll.*'
        )

    def noop_roll(self, prefix='', name='get roll direction'):
        return self.step_data(
            '{}{}.is forward'.format(prefix, name), retcode=0
        ) + self.step_data('{}{}.is backward'.format(prefix, name), retcode=0)

    def forward_roll(self, prefix='', name='get roll direction'):
        return self.step_data(
            '{}{}.is forward'.format(prefix, name), retcode=0
        ) + self.step_data('{}{}.is backward'.format(prefix, name), retcode=1)

    def backward_roll(self, prefix='', name='get roll direction'):
        return self.step_data(
            '{}{}.is forward'.format(prefix, name), retcode=1
        ) + self.step_data('{}{}.is backward'.format(prefix, name), retcode=0)

    def rebased_roll(self, prefix='', name='get roll direction'):
        return self.step_data(
            '{}{}.is forward'.format(prefix, name), retcode=1
        ) + self.step_data('{}{}.is backward'.format(prefix, name), retcode=1)
