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

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

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

PYTHON_VERSION_COMPATIBILITY = "PY3"


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

    # These are determined using Python logic but don't actually show in the
    # output. Adding them to the output both for coverage and to confirm their
    # values.
    with api.step.nest('root') as pres:
        pres.step_summary_text = str(api.checkout.root)
    with api.step.nest('repo_top') as pres:
        pres.step_summary_text = str(api.checkout.repo_top)
    with api.step.nest('use_repo') as pres:
        pres.step_summary_text = str(api.checkout.use_repo)
    with api.step.nest('changes'):
        for i, change in enumerate(api.checkout.changes):
            with api.step.nest(str(i)) as pres:
                pres.step_summary_text = repr(change)
    with api.step.nest('snapshot_to_dir'):
        api.checkout.snapshot_to_dir(api.path['start_dir'].join('snapshot'))


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

    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('ci')
        + api.properties(**api.checkout.repo_properties())
        + api.checkout.manifest_test_data()
        + api.checkout.root_files('foo', 'bar', '.repo')
    )

    yield (
        api.status_check.test('try')
        + api.properties(**api.checkout.repo_properties())
        + api.checkout.try_test_data(REPO)
        + api.checkout.manifest_test_data()
        + api.checkout.root_files('foo', '.repo')
        + api.checkout.all_changes_applied()
    )

    yield (
        api.status_check.test('try-multiple')
        + api.properties(**api.checkout.repo_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.status_check.test('try-multiple-cqdeps')
        + api.properties(**api.checkout.repo_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.status_check.test('try-multiple-onenotapplied')
        + api.properties(**api.checkout.repo_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.status_check.test(
            'try_repo_not_in_manifest', status='infra_failure'
        )
        + api.properties(**api.checkout.repo_properties())
        + api.checkout.try_test_data('https://foo.googlesource.com/bar')
        + api.checkout.manifest_test_data()
        + api.checkout.no_changes_applied()
    )

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

    yield (
        api.status_check.test('feature_branches_try')
        + api.properties(**api.checkout.repo_properties())
        + api.checkout.try_test_data(REPO)
        + api.checkout.cl_branch('feature1')
        + api.checkout.manifest_has_matching_branch('feature1')
        + api.checkout.manifest_test_data()
        + api.checkout.all_changes_applied()
    )

    yield (
        api.status_check.test('feature_branches_try_multiple_features')
        + api.properties(**api.checkout.repo_properties())
        + api.checkout.try_test_data(
            gerrit_changes=[
                cl('pigweed_name', 1234),
                cl('default_name', 2345, name='default'),
            ]
        )
        + api.checkout.cl_branch('feature1', index=0)
        + api.checkout.cl_branch('feature2', index=1)
        + api.checkout.manifest_has_matching_branch('feature1')
        + api.checkout.manifest_test_data()
        + api.checkout.all_changes_applied()
    )

    yield (
        api.status_check.test(
            'feature_branches_try_multiple_matches', status='failure'
        )
        + api.properties(**api.checkout.repo_properties())
        + api.checkout.try_test_data(
            gerrit_changes=[
                cl('pigweed_name', 1234),
                cl('default_name', 2345, name='default'),
            ]
        )
        + api.checkout.cl_branch('feature1', index=0)
        + api.checkout.cl_branch('feature2', index=1)
        + api.checkout.manifest_has_matching_branch('feature1')
        + api.checkout.manifest_has_matching_branch('feature2')
        + api.checkout.all_changes_applied()
    )

    yield (
        api.status_check.test('feature_branches_ci')
        + api.properties(**api.checkout.repo_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.status_check.test('no_trigger')
        + api.properties(**api.checkout.repo_properties())
        + api.checkout.manifest_test_data()
    )

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