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

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


def RunSteps(api):  # pylint: disable=invalid-name
    # No commenting requested.
    api.gerrit_comment.maybe_post(
        Options(
            comment_behavior=CommentBehavior.COMMENT_UNSPECIFIED,
            allowed_gerrit_hosts=["pigweed-review.googlesource.com"],
        ),
        recipe_api.DeferredResult(result=None, failure=None),
    )

    # 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"],
        ),
        recipe_api.DeferredResult(result=None, failure=None),
    )

    # Comment expected.
    api.gerrit_comment.maybe_post(
        Options(
            comment_behavior=CommentBehavior.COMMENT_ALWAYS,
            allowed_gerrit_hosts=["pigweed-review.googlesource.com"],
        ),
        recipe_api.DeferredResult(result=None, failure=None),
    )

    # Comment expected: step failed.
    api.gerrit_comment.maybe_post(
        Options(
            comment_behavior=CommentBehavior.COMMENT_ON_FAILURE,
            allowed_gerrit_hosts=["pigweed-review.googlesource.com"],
        ),
        recipe_api.DeferredResult(
            result="Something went wrong", failure=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"],
        ),
        recipe_api.DeferredResult(result=None, failure=None),
    )


def GenTests(api):  # pylint: disable=invalid-name
    """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()
