# Copyright 2022 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 gerrit_comment module."""

from __future__ import annotations

import datetime
from collections.abc import Iterator

from recipe_engine import recipe_api, recipe_test_api

from PB.recipe_modules.pigweed.gerrit_comment.options import (
    CommentBehavior,
    Options,
)

DEPS = [
    'pigweed/checkout',
    'pigweed/gerrit_comment',
    'recipe_engine/defer',
]


def RunSteps(api: recipe_api.RecipeScriptApi):
    def deferred_result(**kwargs):
        return api.defer.DeferredResult(_api=api, **kwargs)

    # No commenting requested.
    api.gerrit_comment.maybe_post(
        Options(
            comment_behavior=CommentBehavior.COMMENT_UNSPECIFIED,
            allowed_gerrit_hosts=['pigweed-review.googlesource.com'],
        ),
        deferred_result(),
    )

    # Commenting requested only on failure, but this is a pass.
    api.gerrit_comment.maybe_post(
        Options(
            comment_behavior=CommentBehavior.COMMENT_ON_FAILURE,
            allowed_gerrit_hosts=['pigweed-review.googlesource.com'],
        ),
        deferred_result(),
    )

    # Comment expected.
    api.gerrit_comment.maybe_post(
        Options(
            comment_behavior=CommentBehavior.COMMENT_ALWAYS,
            allowed_gerrit_hosts=['pigweed-review.googlesource.com'],
        ),
        deferred_result(),
    )

    # Comment expected: step failed.
    api.gerrit_comment.maybe_post(
        Options(
            comment_behavior=CommentBehavior.COMMENT_ON_FAILURE,
            allowed_gerrit_hosts=['pigweed-review.googlesource.com'],
        ),
        deferred_result(_exc=ValueError('Bad stuff')),
    )

    # Comment not expected: Gerrit host not in allowlist.
    api.gerrit_comment.maybe_post(
        Options(
            comment_behavior=CommentBehavior.COMMENT_ALWAYS,
            allowed_gerrit_hosts=['secret-project.googlesource.com'],
        ),
        deferred_result(),
    )


def GenTests(api) -> Iterator[recipe_test_api.TestData]:
    """Create tests."""

    yield api.test(
        'try-build',
        api.checkout.try_test_data(
            start_time=datetime.datetime.utcfromtimestamp(1600000000),
            execution_timeout=120,
        ),
    )

    yield api.test(
        'ci-build',
        api.checkout.ci_test_data(),
    )
