# 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 repo functionality in checkout module."""

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

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

PROPERTIES = InputProperties

REPO = 'https://pigweed.googlesource.com/pigweed_name'


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

    with api.step.nest('changes'):
        for i, change in enumerate(checkout.changes):
            with api.step.nest(str(i)) as pres:
                pres.step_summary_text = repr(change)
    with api.step.nest('snapshot_to_dir'):
        checkout.snapshot_to_dir(api.path['start_dir'] / 'snapshot')


def GenTests(api):  # pylint: disable=invalid-name
    """Create tests."""

    def properties(**kwargs):
        props = InputProperties(
            checkout_options=api.checkout.repo_options(**kwargs)
        )
        return api.properties(props)

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

    yield (
        api.test('ci')
        + properties()
        + api.checkout.manifest_test_data()
        + api.checkout.root_files('foo', 'bar', '.repo')
    )

    yield (
        api.test('try')
        + properties(manifest_groups=['group1'])
        + api.checkout.try_test_data(REPO)
        + api.checkout.manifest_test_data()
        + api.checkout.root_files('foo', '.repo')
        + api.checkout.all_changes_applied()
        + api.post_process(
            post_process.MustRun,
            'checkout pigweed.no non-standard branch names',
        )
    )

    yield (
        api.test('try-multiple')
        + properties()
        + api.checkout.try_test_data(
            gerrit_changes=[
                cl('pigweed_name', 1234),
                cl('default_name', 2345, name='default'),
            ]
        )
        + api.checkout.manifest_test_data()
        + api.checkout.root_files('foo', '.repo')
        + api.checkout.all_changes_applied()
        + api.checkout.change_applied('pigweed:1234')
        + api.checkout.change_applied('default:2345')
    )

    yield (
        api.test('try-multiple-cqdeps')
        + properties()
        + api.checkout.try_test_data(
            git_repo='https://pigweed.googlesource.com/pigweed_name',
            change_number=1234,
            patch_set=1,
        )
        + api.cq_deps.details(
            'pigweed:1234',
            message='Requires: default:2345',
            prefix='checkout pigweed.change data.process gerrit changes.',
        )
        + api.cq_deps.details(
            'default:2345',
            project='default_name',
            prefix='checkout pigweed.change data.process gerrit changes.',
        )
        + api.checkout.manifest_test_data()
        + api.checkout.root_files('foo', '.repo')
        + api.checkout.all_changes_applied()
        + api.checkout.change_applied('pigweed:1234')
        + api.checkout.change_applied('default:2345')
    )

    yield (
        api.test('try-multiple-onenotapplied')
        + properties()
        + api.checkout.try_test_data(
            gerrit_changes=[
                cl('pigweed_name', 1234),
                cl('default_name', 2345, name='default'),
                cl('project-that-is-not-in-the-manifest', 3456),
            ]
        )
        + api.checkout.manifest_test_data(name='pigweed')
        + api.checkout.root_files('foo', '.repo')
        + api.checkout.some_changes_applied()
        + api.checkout.change_not_applied('pigweed:3456')
    )

    yield (
        api.test('try_repo_not_in_manifest', status='INFRA_FAILURE')
        + properties()
        + api.checkout.try_test_data('https://foo.googlesource.com/bar')
        + api.checkout.manifest_test_data()
        + api.checkout.no_changes_applied()
    )

    yield (
        api.test('try_manifest')
        + properties()
        + api.checkout.try_test_data(api.checkout.manifest_repo)
        + api.checkout.cl_branch_parents('feature-not-in-manifest')
        + api.checkout.manifest_test_data()
        + api.checkout.root_files('foo')
        + api.checkout.all_changes_applied()
    )

    yield (
        api.test('feature_branches_try')
        + properties()
        + api.checkout.try_test_data(REPO)
        + api.checkout.cl_branch_parents('feature1')
        + api.checkout.manifest_has_matching_branch('feature1')
        + api.checkout.manifest_test_data()
        + api.checkout.all_changes_applied()
    )

    yield (
        api.test('feature_branches_try_multiple_features')
        + properties()
        + api.checkout.try_test_data(
            gerrit_changes=[
                cl('pigweed_name', 1234),
                cl('default_name', 2345, name='default'),
            ]
        )
        + api.checkout.cl_branch_parents('feature1', index=0)
        + api.checkout.cl_branch_parents('feature2', index=1)
        + api.checkout.manifest_has_matching_branch('feature1')
        + api.checkout.manifest_test_data()
        + api.checkout.all_changes_applied()
        + api.post_process(
            post_process.DoesNotRun,
            'checkout pigweed.no non-standard branch names',
        )
        + api.post_process(
            post_process.DoesNotRun,
            'checkout pigweed.not matching branch names',
        )
    )

    yield (
        api.test('feature_branches_try_multiple_matches', status='FAILURE')
        + properties()
        + api.checkout.try_test_data(
            gerrit_changes=[
                cl('pigweed_name', 1234),
                cl('default_name', 2345, name='default'),
            ]
        )
        + api.checkout.cl_branch_parents('feature1', index=0)
        + api.checkout.cl_branch_parents('feature2', index=1)
        + api.checkout.manifest_has_matching_branch('feature1')
        + api.checkout.manifest_has_matching_branch('feature2')
        + api.checkout.all_changes_applied()
        + api.post_process(
            post_process.DoesNotRun,
            'checkout pigweed.not matching branch names',
        )
    )

    yield (
        api.test('feature_branches_try_no_matching')
        + properties(match_branch=False)
        + api.checkout.try_test_data(
            gerrit_changes=[
                cl('pigweed_name', 1234),
                cl('default_name', 2345, name='default'),
            ]
        )
        + api.checkout.cl_branch_parents('feature1', index=0)
        + api.checkout.cl_branch_parents('feature2', index=1)
        + api.checkout.manifest_test_data()
        + api.checkout.all_changes_applied()
        + api.post_process(
            post_process.MustRun, 'checkout pigweed.not matching branch names',
        )
    )

    yield (
        api.test('feature_branches_ci')
        + properties()
        + api.checkout.ci_test_data(
            'https://pigweed.googlesource.com/pinned', branch='feature1'
        )
        + api.checkout.manifest_has_matching_branch('feature1')
        + api.checkout.manifest_test_data()
    )

    yield (
        api.test('no_trigger')
        + properties()
        + api.checkout.manifest_test_data()
    )

    yield (
        api.test('prefix')
        + properties()
        + api.checkout.try_test_data(
            "https://foo.googlesource.com/prefix/suffix"
        )
        + api.checkout.manifest_test_data()
        + api.checkout.all_changes_applied()
    )
