# Copyright 2021 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.
"""Utility functions common to multiple recipes that don't fit elsewhere."""

import json
import re

import attr
from google.protobuf import json_format
from recipe_engine import recipe_api


@attr.s
class ChangeWithComments(object):
    change = attr.ib()
    details = attr.ib()
    commit_message = attr.ib()
    comments = attr.ib()


class UtilApi(recipe_api.RecipeApi):
    def get_change_with_comments(self):
        input_ = self.m.buildbucket.build.input
        change = input_.gerrit_changes[0]
        change_id = str(change.change)
        details = self.m.gerrit.change_details(
            'change details',
            change_id=change_id,
            host=input_.gerrit_changes[0].host,
            query_params=['ALL_COMMITS', 'ALL_REVISIONS', 'ALL_FILES'],
            test_data=self.m.json.test_api.output(
                {
                    'owner': {'email': 'coder@example.com',},
                    'current_revision': 'a' * 40,
                    'revisions': {
                        'a'
                        * 40: {
                            'files': [],
                            'commit': {'message': '',},
                            'description': 'description',
                        }
                    },
                    'revert_of': 0,
                }
            ),
        ).json.output

        current_revision = details['revisions'][details['current_revision']]
        commit_message = current_revision['commit']['message']

        comments = []

        for revision in details['revisions'].values():
            if revision.get('description'):
                comments.append(revision['description'])

        comments_result = self.m.gerrit.list_change_comments(
            "list change comments",
            change_id,
            test_data=self.m.json.test_api.output(
                {'/PATCHSET_LEVEL': [{'message': ''}],}
            ),
        ).json.output

        for _, comment_data in comments_result.items():
            comments.extend(x['message'] for x in comment_data)

        return ChangeWithComments(change, details, commit_message, comments)

    def find_matching_comment(self, rx, comments):
        """Find a comment in comments that matches regex object rx."""
        result = None
        with self.m.step.nest('checking comments'):
            for i, comment in enumerate(comments):
                with self.m.step.nest('comment ({})'.format(i)) as pres:
                    pres.step_summary_text = comment
                    match = re.search(rx, comment)
                    if match:
                        pres.step_summary_text = 'MATCH: {}'.format(comment)
                        result = match
                        break

            if result:
                with self.m.step.nest('found'):
                    pass

        return result

    def build_metadata(self):
        return {
            'bb_id': self.m.buildbucket.build.id,
            'swarming_id': self.m.swarming.task_id,
            'builder': self.m.buildbucket_util.full_builder_name(),
            'url': self.m.buildbucket_util.build_url,
            'triggers': [
                json.loads(json_format.MessageToJson(x))
                for x in self.m.scheduler.triggers
            ],
        }
