# 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."""

import datetime
from typing import Generator

from PB.recipe_modules.pigweed.gerrit_comment.options import (
    CommentBehavior,
    Options,
)
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()
