# 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.
"""Full test of submodule functionality of checkout module."""

from PB.recipe_modules.pigweed.checkout.tests.properties import InputProperties

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

PROPERTIES = InputProperties


def RunSteps(api, props):  # pylint: disable=invalid-name
    checkout = api.checkout(props.checkout_options)

    with api.step.nest('snapshot_to_dir'):
        checkout.snapshot_to_dir(api.path['start_dir'].join('snapshot'))


def GenTests(api):  # pylint: disable=invalid-name
    def props(**kwargs):
        kwargs.setdefault('initialize_submodules', False)
        kwargs.setdefault(
            'remote', 'https://pigweed.googlesource.com/pigweed/pigweed.git'
        )
        kwargs.setdefault('branch', None)

        return api.properties(**api.checkout.git_properties(**kwargs))

    submodule_data = api.checkout.submodules(
        api.checkout.submodule('foo', 'https://x.googlesource.com/foo', '-'),
        api.checkout.submodule('bar', 'https://x.googlesource.com/bar', '+'),
        api.checkout.submodule('baz', 'https://x.googlesource.com/baz.git'),
        # Using 'b/c/d' instead of 'a/b/c' because an 'a/' prefix is treated
        # specially by Gerrit and the buildbucket module.
        api.checkout.submodule(
            'b/c/d', 'https://x.googlesource.com/b/c/d', ' '
        ),
    )

    yield (
        api.status_check.test('submodule-try')
        + props()
        + api.checkout.try_test_data(git_repo='https://x.googlesource.com/baz')
        + submodule_data
        + api.checkout.all_changes_applied()
    )

    yield (
        api.status_check.test('submodule-ci')
        + props()
        + api.checkout.ci_test_data(git_repo='https://x.googlesource.com/b/c/d')
        + submodule_data
    )

    yield (
        api.status_check.test('submodule-try-not-found', status='infra_failure')
        + props()
        + api.checkout.try_test_data(git_repo='https://x.googlesource.com/xyz')
        + submodule_data
        + api.checkout.no_changes_applied()
    )

    yield (
        api.status_check.test('submodule-try-equivalent')
        + props(
            equivalent_remotes=(
                (
                    'https://z.googlesource.com/foo',
                    'https://x.googlesource.com/foo',
                ),
            ),
        )
        + api.checkout.try_test_data(git_repo='https://z.googlesource.com/foo')
        + submodule_data
        + api.checkout.all_changes_applied()
    )

    def cl(project, change, patchset=1, name='pigweed'):
        return api.checkout.cl(
            host='{}-review.googlesource.com'.format(name),
            project=project,
            change=change,
            patchset=patchset,
        )

    yield (
        api.status_check.test('submodule-try-multiple')
        + props()
        + api.checkout.try_test_data(
            gerrit_changes=[
                cl('foo', 1234, name='x'),
                cl('bar', 2345, name='x'),
                cl('pigweed/pigweed', 3456),
            ]
        )
        + submodule_data
        + api.checkout.all_changes_applied()
        + api.checkout.change_applied('x:1234')
        + api.checkout.change_applied('x:2345')
        + api.checkout.change_applied('pigweed:3456')
    )

    yield (
        api.status_check.test('submodule-try-multiple-one-missing')
        + props()
        + api.checkout.try_test_data(
            gerrit_changes=[
                cl('foo', 1234, name='x'),
                cl('not-a-submodule', 2345, name='x'),
                cl('pigweed/pigweed', 3456),
            ]
        )
        + submodule_data
        + api.checkout.some_changes_applied()
        + api.checkout.change_applied('x:1234')
        + api.checkout.change_not_applied('x:2345')
        + api.checkout.change_applied('pigweed:3456')
    )

    # These tests are nominally identical to 'submodule-try-multiple' and
    # 'submodule-try-multiple-one-missing' above but use the cq_deps module.
    # After the 'process gerrit changes' step all changes are minor (e.g.
    # '2345' instead of '2345L').
    yield (
        api.status_check.test('submodule-try-multiple-cqdeps')
        + props()
        + api.checkout.try_test_data(
            git_repo='https://x.googlesource.com/foo',
            change_number=1234,
            patch_set=1,
        )
        + api.cq_deps.details(
            'x:1234',
            message='Requires: x:2345,pigweed:3456',
            prefix='checkout pigweed.change data.process gerrit changes.',
        )
        + api.cq_deps.details(
            'x:2345',
            project='bar',
            prefix='checkout pigweed.change data.process gerrit changes.',
        )
        + api.cq_deps.details(
            'pigweed:3456',
            project='pigweed/pigweed',
            prefix='checkout pigweed.change data.process gerrit changes.',
        )
        + submodule_data
        + api.checkout.all_changes_applied()
        + api.checkout.change_applied('x:1234')
        + api.checkout.change_applied('x:2345')
        + api.checkout.change_applied('pigweed:3456')
    )

    yield (
        api.status_check.test(
            'submodule-try-multiple-one-missing-one-forbidden-cqdeps'
        )
        + props()
        + api.checkout.try_test_data(
            git_repo='https://x.googlesource.com/foo',
            change_number=1234,
            patch_set=1,
        )
        + api.cq_deps.details(
            'x:1234',
            message='Requires: x:2345,pigweed:3456,forbidden:9999',
            prefix='checkout pigweed.change data.process gerrit changes.',
        )
        + api.cq_deps.details(
            'x:2345',
            project='not-a-submodule',
            prefix='checkout pigweed.change data.process gerrit changes.',
        )
        + api.cq_deps.details(
            'pigweed:3456',
            project='pigweed/pigweed',
            prefix='checkout pigweed.change data.process gerrit changes.',
        )
        + api.cq_deps.forbidden(
            'forbidden:9999',
            prefix='checkout pigweed.change data.process gerrit changes.',
        )
        + submodule_data
        + api.checkout.some_changes_applied()
        + api.checkout.change_applied('x:1234')
        + api.checkout.change_not_applied('x:2345')
        + api.checkout.change_not_applied('forbidden:9999')
        + api.checkout.change_applied('pigweed:3456')
    )

    yield (
        api.status_check.test(
            'submodule-try-included-excluded', status='infra_failure'
        )
        + props(included_submodules=['foo'], excluded_submodules=['bar'])
        + api.checkout.ci_test_data()
    )

    yield (
        api.status_check.test('submodule-try-included')
        + props(included_submodules=['nanopb'])
        + api.checkout.ci_test_data()
        + api.checkout.included_submodule('nanopb')
    )

    yield (
        api.status_check.test('submodule-try-excluded')
        + props(excluded_submodules=['nanopb'])
        + api.checkout.ci_test_data()
        + api.checkout.excluded_submodule('nanopb')
    )

    yield (
        api.status_check.test(
            'submodule-try-excluded-missing', status='infra_failure'
        )
        + props(excluded_submodules=['missing'])
        + api.checkout.ci_test_data()
    )
