# 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 typing import TYPE_CHECKING

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

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

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


def RunSteps(api):  # pylint: disable=invalid-name
    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) -> Generator[recipe_test_api.TestData, None, None]:
    """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(),
    )
