# 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 one repository."""

from recipe_engine.config import List
from recipe_engine.recipe_api import Property

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

PROPERTIES = {
    'project_name': Property(kind=str),
    'original_commits': Property(kind=List),
    'old_revision': Property(kind=str),
    'new_revision': Property(kind=str),
}

PYTHON_VERSION_COMPATIBILITY = "PY3"


def RunSteps(  # pylint: disable=invalid-name
    api, project_name, old_revision, new_revision
):
    proj_dir = api.path['start_dir'].join('project')

    direction = api.roll_util.get_roll_direction(
        api.path['checkout'], old_revision, new_revision
    )
    if api.roll_util.can_roll(direction):
        roll = api.roll_util.Roll(
            project_name=project_name,
            old_revision=old_revision,
            new_revision=new_revision,
            proj_dir=proj_dir,
            direction=direction,
        )

        def steplog(name, value):
            with api.step.nest(name) as pres:
                pres.step_summary_text = repr(value)

        steplog('remote', roll.remote)
        steplog('gerrit_name', roll.gerrit_name)

        with api.step.nest('emails') as pres:
            pres.logs['authors'] = sorted(
                x.email for x in api.roll_util.authors(roll)
            )
            pres.logs['reviewers'] = sorted(
                x.email for x in api.roll_util.reviewers(roll)
            )

        api.roll_util.message(roll)

    else:
        api.roll_util.skip_roll_step('remote', old_revision, new_revision)

    host = 'pigweed-review.googlesource.com'

    api.roll_util.can_cc_on_roll('email@example.com', host)
    api.roll_util.can_cc_on_roll('nobody@google.com', host)

    Account = api.roll_util.Account
    user = Account('user', 'user@example.com')

    assert (
        api.roll_util.fake_author(user).email
        == 'user@pigweed.infra.roller.example.com'
    )

    with api.step.nest('CCing'):
        api.roll_util.include_cc(user, ('example.com',), host)
    with api.step.nest('not CCing, domain excluded'):
        api.roll_util.include_cc(user, ('google.com',), host)
    with api.step.nest('not CCing, robot account'):
        api.roll_util.include_cc(
            Account('robot', 'robot@gserviceaccount.com'), (), host,
        )
    with api.step.nest('not CCing, no account in Gerrit'):
        api.roll_util.include_cc(
            Account('nobody', 'nobody@google.com'), (), host,
        )


def GenTests(api):  # pylint: disable=invalid-name
    yield (
        api.status_check.test('singlecommit_singleline')
        + api.properties(
            project_name='proj', old_revision='0' * 40, new_revision='1' * 40
        )
        + api.roll_util.commit_data(
            'proj',
            api.roll_util.commit('1' * 40, 'foo\n\nbar\n\nChange-Id: I11111'),
        )
        + api.roll_util.forward_roll()
        + api.roll_util.not_cancelled()
    )

    yield (
        api.status_check.test('singlecommit_multiline')
        + api.properties(
            project_name='proj', old_revision='0' * 40, new_revision='1' * 40
        )
        + api.roll_util.commit_data(
            'proj',
            api.roll_util.commit(
                '1' * 40,
                'foo\n\nbar\n\nBug: 123\nCC: foo\nFoo-Auto-Submit: true\n',
            ),
        )
        + api.roll_util.forward_roll()
        + api.roll_util.not_cancelled()
    )

    yield (
        api.status_check.test('multicommit')
        + api.properties(
            project_name='proj', old_revision='0' * 40, new_revision='4' * 40
        )
        + api.roll_util.commit_data(
            'proj',
            api.roll_util.commit('4' * 40, 'xyz\n\nxyz'),
            api.roll_util.commit('3' * 40, 'baz\n\nbaz'),
            api.roll_util.commit(
                '2' * 40, ''.join(x * 10 for x in '0123456789')
            ),
            api.roll_util.commit('1' * 40, 'foo\n\nfoo'),
        )
        + api.roll_util.forward_roll()
        + api.roll_util.not_cancelled()
    )

    yield (
        api.status_check.test('frombranch')
        + api.properties(
            project_name='proj', old_revision='main', new_revision='5' * 40
        )
        + api.roll_util.commit_data(
            'proj',
            api.roll_util.commit('5' * 40, 'five'),
            api.roll_util.commit('4' * 40, 'four'),
            api.roll_util.commit('3' * 40, 'three'),
            api.roll_util.commit('2' * 40, 'two'),
            api.roll_util.commit('1' * 40, 'one'),
        )
        + api.roll_util.forward_roll()
        + api.roll_util.not_cancelled()
    )

    yield (
        api.status_check.test('backwards')
        + api.properties(
            project_name='proj', old_revision='0' * 40, new_revision='1' * 40
        )
        + api.roll_util.backward_roll()
        + api.roll_util.cancelled()
    )

    yield (
        api.status_check.test('up_to_date')
        + api.properties(
            project_name='proj', old_revision='1' * 40, new_revision='1' * 40
        )
        + api.roll_util.cancelled()
    )

    yield (
        api.status_check.test('up_to_date_testonly')
        + api.properties(
            project_name='proj', old_revision='1' * 40, new_revision='2' * 40
        )
        + api.roll_util.noop_roll()
        + api.roll_util.cancelled()
    )

    yield (
        api.status_check.test('rebase')
        + api.properties(
            project_name='proj', old_revision='0' * 40, new_revision='5' * 40
        )
        + api.roll_util.commit_data(
            'proj',
            api.roll_util.commit('5' * 40, 'five'),
            api.roll_util.commit('4' * 40, 'four'),
            api.roll_util.commit('3' * 40, 'three'),
            api.roll_util.commit('2' * 40, 'two'),
            api.roll_util.commit('1' * 40, 'one'),
        )
        + api.roll_util.rebased_roll()
        + api.roll_util.not_cancelled()
    )
