# 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 the cq_deps module."""

from __future__ import annotations

from typing import TYPE_CHECKING

from recipe_engine import recipe_api

if TYPE_CHECKING:  # pragma: no cover
    from typing import Generator
    from recipe_engine import recipe_test_api

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

PROPERTIES = {
    'revision': recipe_api.Property(kind=str, default=None),
    'topic': recipe_api.Property(kind=str, default=None),
}


def RunSteps(api, revision, topic):
    result = api.cq_deps.resolve('pigweed', revision or 1, topic)

    with api.step.nest('final deps'):
        for dep in result.resolved:
            with api.step.nest(dep.name) as pres:
                pres.step_summary_text = dep.remote
                _ = dep.gerrit_url  # For coverage.

    if result.unresolved:
        with api.step.nest('errors'):
            for error in result.unresolved:
                with api.step.nest(error.name):
                    pass


def GenTests(api) -> Generator[recipe_test_api.TestData, None, None]:
    yield api.test(
        'default',
        api.properties(revision='b' * 40),
        api.cq_deps.lookup_cl('b' * 40, 1),
        api.cq_deps.details('pigweed:1'),
    )

    yield api.test(
        'hash',
        api.properties(revision='b' * 40),
        api.cq_deps.lookup_cl('b' * 40, 1),
        api.cq_deps.details('pigweed:1', patches_json=True),
        api.cq_deps.patches_json('pigweed:1'),
    )

    yield api.test(
        'cl-not-found',
        api.properties(revision='b' * 40),
        api.cq_deps.lookup_cl('b' * 40, found=False),
    )

    yield api.test(
        'no-patches-json',
        api.cq_deps.details('pigweed:1', patches_json=True),
        api.cq_deps.patches_json_error('pigweed:1'),
        api.cq_deps.lacks_deps('pigweed:1'),
        status='INFRA_FAILURE',
    )

    yield api.test(
        'one',
        api.cq_deps.details('pigweed:1', patches_json=True),
        api.cq_deps.patches_json('pigweed:1', 'pigweed:2'),
        api.cq_deps.has_deps('pigweed:2'),
        api.cq_deps.lacks_deps('pigweed:1'),
    )

    yield api.test(
        'two',
        api.cq_deps.details('pigweed:1', patches_json=True),
        api.cq_deps.patches_json('pigweed:1', 'pigweed:2', 'pigweed:3'),
        api.cq_deps.has_deps('pigweed:2', 'pigweed:3'),
    )

    yield api.test(
        'no_space',
        api.cq_deps.details('pigweed:1', patches_json=True),
        api.cq_deps.patches_json('pigweed:1', 'pigweed:2', 'pigweed:3'),
        api.cq_deps.has_deps('pigweed:2', 'pigweed:3'),
    )

    yield api.test(
        'loop_two',
        api.cq_deps.details('pigweed:1', patches_json=True),
        api.cq_deps.patches_json('pigweed:1', 'pigweed:2'),
        api.cq_deps.details('pigweed:2', patches_json=True),
        api.cq_deps.patches_json('pigweed:2', 'pigweed:1'),
        api.cq_deps.has_deps('pigweed:2'),
    )

    yield api.test(
        'loop_three',
        api.cq_deps.details('pigweed:1', patches_json=True),
        api.cq_deps.details('pigweed:2', patches_json=True),
        api.cq_deps.details('pigweed:3', patches_json=True),
        api.cq_deps.patches_json('pigweed:1', 'pigweed:2'),
        api.cq_deps.patches_json('pigweed:2', 'pigweed:3'),
        api.cq_deps.patches_json('pigweed:3', 'pigweed:1'),
        api.cq_deps.has_deps('pigweed:2', 'pigweed:3'),
    )

    yield api.test(
        'abandoned',
        api.cq_deps.details('pigweed:1', patches_json=True),
        api.cq_deps.patches_json('pigweed:1', 'pigweed:2'),
        api.cq_deps.details('pigweed:2', patches_json=True, status='ABANDONED'),
        api.cq_deps.lacks_deps('pigweed:2'),
    )

    yield api.test(
        'merged_skipped',
        api.properties(),
        api.cq_deps.details('pigweed:1', patches_json=True),
        api.cq_deps.patches_json('pigweed:1', 'pigweed:2'),
        api.cq_deps.details('pigweed:2', status='MERGED'),
        api.cq_deps.lacks_deps('pigweed:2', 'pigweed:3'),
    )

    yield api.test(
        'error',
        api.cq_deps.details('pigweed:1', patches_json=True),
        api.cq_deps.patches_json('pigweed:1', 'pigweed:2'),
        api.cq_deps.transient('pigweed:2'),
        api.cq_deps.transient('pigweed:2', n=2),
        api.cq_deps.lacks_deps('forbidden:1'),
    )

    yield api.test(
        'error_recovery',
        api.cq_deps.details('pigweed:1', patches_json=True),
        api.cq_deps.patches_json('pigweed:1', 'pigweed:2'),
        api.cq_deps.transient('pigweed:2'),
        api.cq_deps.details('pigweed:2', '', n=2),
        api.cq_deps.has_deps('pigweed:2'),
    )

    yield api.test(
        'forbidden',
        api.cq_deps.details('pigweed:1', patches_json=True),
        api.cq_deps.patches_json('pigweed:1', 'forbidden:2'),
        api.cq_deps.forbidden('forbidden:2'),
        api.cq_deps.lacks_deps('forbidden:2'),
    )

    yield api.test(
        'patches_json_disabled',
        api.properties(**api.cq_deps.properties(patches_json_disabled=True)),
        api.cq_deps.details('pigweed:1', patches_json=True),
        api.cq_deps.lacks_deps('pigweed:1', 'pigweed:2'),
    )

    yield api.test(
        'topics',
        api.properties(
            topic='topic',
            **api.cq_deps.properties(
                patches_json_disabled=True,
                topics_enabled=True,
            ),
        ),
        api.cq_deps.lacks_deps('pigweed:1'),
        api.cq_deps.has_deps('pigweed:2'),
    )

    yield api.test(
        'topics-disabled',
        api.properties(topic='topic'),
        api.cq_deps.lacks_deps('pigweed:1', 'pigweed:2'),
    )
