# 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 collections.abc import Iterator

from recipe_engine import recipe_api, recipe_test_api

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

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

INLINE_PROPERTIES_PROTO = """
import "recipe_modules/pigweed/checkout/options.proto";

message InputProperties {
  // Checkout module options.
  recipe_modules.pigweed.checkout.Options checkout_options = 1;
}
"""

PROPERTIES = InputProperties


def RunSteps(api: recipe_api.RecipeScriptApi, props: InputProperties):
    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())

    triggering_changes = api.checkout.triggering_changes(props.checkout_options)
    if triggering_changes:
        assert len(checkout.changes) == len(triggering_changes)


def GenTests(api) -> Iterator[recipe_test_api.TestData]:
    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_pb.Trigger(
                    gitiles=triggers_pb.GitilesTrigger(
                        repo='https://pigweed.googlesource.com/pigweed/pigweed',
                        revision='2d72510e447ab60a9728aeea2362d8be2cbd7789',
                        ref='refs/heads/overridden-by-trigger',
                    ),
                ),
            ],
        ),
    )

    yield api.test(
        'try',
        properties(root_subdirectory='foo', use_packfiles=False),
        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',
        properties(),
        api.step_data('checkout pigweed.cache.git fetch', retcode=1),
        api.step_data('checkout pigweed.cache.git fetch (2)', retcode=1),
        status='INFRA_FAILURE',
    )

    yield api.test(
        'multiple-same-remote',
        properties(),
        api.checkout.try_test_data(
            gerrit_changes=[
                api.checkout.cl('pigweed-review.googlesource.com', 'foo', 1000),
                api.checkout.cl('pigweed-review.googlesource.com', 'foo', 2000),
            ]
        ),
        api.checkout.multiple_changes_for_same_repo(),
        status='FAILURE',
    )

    yield api.test(
        'multiple-equiv-remote',
        properties(
            equivalent_remotes=(
                (
                    'https://pigweed.googlesource.com/foo',
                    'https://pigweed.googlesource.com/bar',
                ),
            ),
        ),
        api.checkout.try_test_data(
            gerrit_changes=[
                api.checkout.cl('pigweed-review.googlesource.com', 'foo', 1000),
                api.checkout.cl('pigweed-review.googlesource.com', 'bar', 2000),
            ]
        ),
        api.checkout.multiple_changes_for_same_repo(),
        status='FAILURE',
    )

    # TODO: b/400532999 - Remove hard-coded equivalency support.
    yield api.test(
        'hardcoded-equiv-remote-multiple',
        properties(
            equivalent_remotes=(
                (
                    'https://pigweed.googlesource.com/foo',
                    'https://pigweed.googlesource.com/pigweed/pigweed',
                ),
            ),
        ),
        api.checkout.try_test_data(
            gerrit_changes=[
                api.checkout.cl('pigweed-review.googlesource.com', 'foo', 1000),
                api.checkout.cl(
                    'fuchsia-review.googlesource.com',
                    'third_party/pigweed.googlesource.com/pigweed/pigweed',
                    2000,
                ),
            ]
        ),
        api.checkout.multiple_changes_for_same_repo(),
        status='FAILURE',
    )
