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

from __future__ import annotations

from typing import TYPE_CHECKING

from PB.go.chromium.org.luci.scheduler.api.scheduler.v1 import (
    triggers as triggers_pb2,
)
from PB.recipe_modules.pigweed.checkout.tests.properties import InputProperties

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

DEPS = [
    'pigweed/checkout',
    'recipe_engine/json',
    'recipe_engine/properties',
    'recipe_engine/scheduler',
    'recipe_engine/step',
]

PROPERTIES = InputProperties


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

    def steplog(name, value):  # pylint: disable=invalid-name
        with api.step.nest(name) as pres:
            pres.step_summary_text = repr(value)

    # These lines are needed for coverage.
    steplog('revision', checkout.revision())
    steplog('revision', checkout.revision())  # Intentional repeat (caching).
    steplog('gerrit_host', checkout.gerrit_host())
    steplog('gerrit_project', checkout.gerrit_project())
    steplog('submodules', checkout.submodules())
    steplog('applied_changes', checkout.applied_changes())


def GenTests(api) -> Generator[recipe_test_api.TestData, None, None]:
    def properties(**kwargs):
        kwargs.setdefault('remote', api.checkout.pigweed_repo)
        kwargs.setdefault('branch', None)
        props = InputProperties(
            checkout_options=api.checkout.git_options(**kwargs)
        )
        return api.properties(props)

    yield api.test('ci') + properties() + api.checkout.ci_test_data()

    yield (
        api.test('trigger')
        + properties()
        + api.checkout.ci_test_data()
        + api.scheduler(
            triggers=[
                triggers_pb2.Trigger(
                    gitiles=triggers_pb2.GitilesTrigger(
                        repo='https://pigweed.googlesource.com/pigweed/pigweed',
                        revision='2d72510e447ab60a9728aeea2362d8be2cbd7789',
                        ref='refs/heads/overridden-by-trigger',
                    ),
                ),
            ],
        )
    )

    yield (
        api.test('try')
        + properties(root_subdirectory='foo')
        + api.checkout.try_test_data()
        + api.checkout.cl_branch_parents(num_parents=2)
    )

    yield api.test('other') + properties()

    yield (
        api.test('not_in_gerrit')
        + properties()
        + api.step_data(
            'checkout pigweed.change data.number',
            api.json.output({}),
        )
    )

    yield (
        api.test('fail-config', status='INFRA_FAILURE')
        + properties()
        + api.step_data('checkout pigweed.cache.git fetch', retcode=1)
    )
