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

from __future__ import annotations

from typing import TYPE_CHECKING

from recipe_engine import recipe_api

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

if TYPE_CHECKING:  # pragma: no cover
    from RECIPE_MODULES.recipe_engine.defer import api as defer_api


class GerritCommentApi(recipe_api.RecipeApi):
    def maybe_post(self, options: Options, result: defer_api.DeferredResult):
        """Maybe post a comment on a Gerrit CL.

        Post a comment on the CL associated with this build (or not, depending
        on the options).

        Args:
          options: Options.
          result: DeferredResult object.
        """
        if options.comment_behavior == CommentBehavior.COMMENT_UNSPECIFIED:
            return

        with self.m.step.nest("maybe post") as pres:
            if (
                options.comment_behavior == CommentBehavior.COMMENT_ON_FAILURE
                and result.is_ok()
            ):
                pres.step_summary_text = (
                    "No-op: Comments requested only on failures, "
                    "but the step passed."
                )
                return

            changes = self.m.buildbucket.build.input.gerrit_changes
            if len(changes) == 0:
                pres.step_summary_text = (
                    "No-op: no Gerrit change to comment on "
                    "(expected for CI builds)."
                )
                return

            change = changes[-1]
            if (
                self.m.gerrit.normalize_host(change.host)
                not in options.allowed_gerrit_hosts
            ):
                pres.step_summary_text = (
                    "No-op: "
                    "the change is on a host that's not explicitly allowlisted."
                )
                return

            # If we made it here, we should post a comment on the CL.
            pres.step_summary_text = "Posting CL comment"
            if result.is_ok():
                status = "OK"
            else:
                try:
                    result.result()
                    assert False, "shouldn't get here"  # pragma: no cover
                except Exception as exc:
                    status = str(exc)

            self.m.gerrit.set_review(
                "post CL comment",
                change.change,
                host=change.host,
                message="{} completed with status {}: http://go/bbid/{}".format(
                    self.m.buildbucket.builder_name,
                    status,
                    self.m.buildbucket.build.id,
                ),
                notify="OWNER",
            )
