# 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.
"""Set a "Verified" label with the results of CQ.

Find CLs where CQ has completed and set a label to +1 or -1 based on the status
of CQ. Also find CLs where CQ is running and clear that +1 or -1.
"""

import collections
import re

from recipe_engine import post_process, recipe_test_api
from PB.go.chromium.org.luci.buildbucket.proto import common
from PB.recipe_engine import result
from PB.recipes.pigweed.cq_label import InputProperties

DEPS = [
    'fuchsia/gerrit',
    'fuchsia/status_check',
    'recipe_engine/json',
    'recipe_engine/properties',
    'recipe_engine/step',
]

PROPERTIES = InputProperties

PYTHON_VERSION_COMPATIBILITY = 'PY3'


def _summary(api, host, change_id, action):
    return '[{change_id}](https://{host}/{change_id}): {action}'.format(
        change_id=change_id,
        host=api.gerrit.normalize_host(host),
        action=action,
    )


def _label_completed_unlabelled(
    api, host, projects, label, cq_account, dry_run,
):
    query_string = (
        'is:open '
        '-(label:Commit-Queue+1 OR label:Commit-Queue+2) '
        '-(label:{label}-1 OR label:{label}+1) '
        '(r:{cq_account} OR cc:{cq_account}) '
        '({project_part}) '
    ).format(
        label=label,
        cq_account=cq_account,
        project_part=' OR '.join('project:{}'.format(p) for p in projects),
    )

    changes = (
        api.gerrit.change_query(
            name='get unlabeled changes',
            query_string=query_string,
            host=host,
            max_attempts=5,
            timeout=30,
        )
        .get_result()
        .json.output
    )

    for change in changes or ():
        change_id = str(change['_number'])

        with api.step.nest(change_id) as pres:
            pres.links[change_id] = 'https://{}/{}'.format(
                api.gerrit.normalize_host(host), change_id,
            )

            details = (
                api.gerrit.change_details(
                    'details',
                    change_id,
                    query_params=['CURRENT_REVISION'],
                    host=host,
                )
                .get_result()
                .json.output
            )

            patch = details['revisions'][details['current_revision']]['_number']
            value = 0
            # Look at messages in reverse order so we always set based on the
            # most recent CQ results.
            for message in reversed(details['messages']):
                if message['author']['email'] != cq_account:
                    continue

                passed = re.search(
                    r'Patch Set {}:\s*Dry run: This CL passed'.format(patch),
                    message['message'],
                    re.IGNORECASE,
                )
                if passed:
                    with api.step.nest('passed'):
                        value = 1
                        break

                failed = re.search(
                    r'Patch Set {}:\s*Dry run: Failed builds'.format(patch),
                    message['message'],
                    re.IGNORECASE,
                )
                if failed:
                    with api.step.nest('failed'):
                        value = -1
                        break

            if value:
                if dry_run:
                    action = 'would set {} to {}'.format(label, value)
                    pres.step_summary_text = action
                    with api.step.nest(action):
                        pass

                else:
                    action = 'set {} to {}'.format(label, value)
                    pres.step_summary_text = action
                    api.gerrit.set_review(
                        action,
                        change_id,
                        labels={label: value},
                        host=host,
                        notify='NONE',
                    )

                yield _summary(api, host, change_id, action)

            else:
                pres.step_summary_text = 'no action'


def _remove_running_labelled(api, host, projects, label, cq_account, dry_run):
    query_string = (
        'is:open '
        '(label:Commit-Queue+1 OR label:Commit-Queue+2) '
        '(label:{label}-1 OR label:{label}+1) '
        '(r:{cq_account} OR cc:{cq_account}) '
        '({project_part}) '
    ).format(
        label=label,
        cq_account=cq_account,
        project_part=' OR '.join('project:{}'.format(p) for p in projects),
    )

    changes = (
        api.gerrit.change_query(
            name='get labeled changes',
            query_string=query_string,
            host=host,
            max_attempts=5,
            timeout=30,
        )
        .get_result()
        .json.output
    )

    for change in changes or ():
        change_id = str(change['_number'])

        with api.step.nest(change_id) as pres:
            pres.links[change_id] = 'https://{}/{}'.format(
                api.gerrit.normalize_host(host), change_id,
            )

            if dry_run:
                action = 'would clear {}'.format(label)
                pres.step_summary_text = action
                with api.step.nest(action):
                    pass

            else:
                action = 'clear {}'.format(label)
                pres.step_summary_text = action
                api.gerrit.set_review(
                    action,
                    change_id,
                    labels={label: 0},
                    host=host,
                    notify='NONE',
                )

            yield _summary(api, host, change_id, action)


def RunSteps(api, props):
    assert re.match(r'^[-\w]+$', props.label)
    assert re.match(r'^[-\w.@]+$', props.cq_account)

    with api.step.nest('properties') as pres:
        pres.step_summary_text = repr(api.properties.thaw())

    projects_by_host = collections.defaultdict(list)
    for repo in props.repo:
        match = re.search(
            r'^https://(?P<host>.*).googlesource.com/(?P<project>.*)$', repo,
        )
        assert match, repo
        host = match.group('host')
        project = match.group('project')
        projects_by_host[host].append(project)

    actions = []

    with api.step.defer_results():
        for host, projects in projects_by_host.items():
            with api.step.nest(host):
                actions.extend(
                    _label_completed_unlabelled(
                        api=api,
                        host=host,
                        projects=projects,
                        label=props.label,
                        cq_account=props.cq_account,
                        dry_run=props.dry_run,
                    )
                )

                actions.extend(
                    _remove_running_labelled(
                        api=api,
                        host=host,
                        projects=projects,
                        label=props.label,
                        cq_account=props.cq_account,
                        dry_run=props.dry_run,
                    )
                )

    return result.RawResult(
        summary_markdown='\n\n'.join(actions), status=common.SUCCESS,
    )


def GenTests(api):
    CQ_BOT_ACCOUNT = 'cq-bot-account@gserviceaccount.com'
    VERIFIED_LABEL = 'CQ-Verified'
    PROJECT = 'pigweed'

    def properties(**kwargs):
        new_kwargs = {
            'repo': ['https://pigweed.googlesource.com/{}'.format(PROJECT)],
            'cq_account': CQ_BOT_ACCOUNT,
            'label': VERIFIED_LABEL,
        }
        new_kwargs.update(**kwargs)
        return api.properties(**new_kwargs)

    def unlabeled_query_results(project='pigweed'):
        return api.step_data(
            'pigweed.get unlabeled changes',
            api.json.output([{'_number': 1, 'project': project}]),
        )

    def labeled_query_results(project='pigweed'):
        return api.step_data(
            'pigweed.get labeled changes',
            api.json.output([{'_number': 1, 'project': project}]),
        )

    def message(patch_set, passed, author=CQ_BOT_ACCOUNT):
        return {
            'author': {'email': author,},
            'message': 'Patch Set {}: Dry run: {}'.format(
                patch_set, 'This CL passed' if passed else 'Failed builds',
            ),
        }

    def details(*messages, **kwargs):
        res = {
            'current_revision': 'h3110',
            'revisions': {'h3110': {'_number': 2}},
            'messages': list(messages),
            'project': PROJECT,
        }
        res.update(kwargs)
        return api.step_data('pigweed.1.details', api.json.output(res))

    def set_passed(label=VERIFIED_LABEL, dry_run=False):
        dry_run_part = 'would ' if dry_run else ''
        return api.post_process(
            post_process.MustRun,
            'pigweed.1.{}set {} to 1'.format(dry_run_part, label),
        )

    def set_failed(label=VERIFIED_LABEL, dry_run=False):
        dry_run_part = 'would ' if dry_run else ''
        return api.post_process(
            post_process.MustRun,
            'pigweed.1.{}set {} to -1'.format(dry_run_part, label),
        )

    def no_set(label=VERIFIED_LABEL):
        return (
            api.post_process(
                post_process.DoesNotRun, 'pigweed.1.set {} to 1'.format(label),
            )
            + api.post_process(
                post_process.DoesNotRun,
                'pigweed.1.would set {} to 1'.format(label),
            )
            + api.post_process(
                post_process.DoesNotRun, 'pigweed.1.set {} to -1'.format(label),
            )
            + api.post_process(
                post_process.DoesNotRun,
                'pigweed.1.would set {} to -1'.format(label),
            )
        )

    def does_not_clear(label=VERIFIED_LABEL):
        return api.post_process(
            post_process.DoesNotRun, 'pigweed.1.clear {}'.format(label),
        ) + api.post_process(
            post_process.DoesNotRun, 'pigweed.1.would clear {}'.format(label),
        )

    def clear(label=VERIFIED_LABEL, dry_run=False):
        dry_run_part = 'would ' if dry_run else ''
        return api.post_process(
            post_process.MustRun,
            'pigweed.1.{}clear {}'.format(dry_run_part, label),
        )

    yield (
        api.status_check.test('passed')
        + properties()
        + unlabeled_query_results()
        + details(message(2, True))
        + set_passed()
        + does_not_clear()
    )

    yield (
        api.status_check.test('failed')
        + properties()
        + unlabeled_query_results()
        + details(message(2, False))
        + set_failed()
        + does_not_clear()
    )

    yield (
        api.status_check.test('wrong-author')
        + properties()
        + unlabeled_query_results()
        + details(message(2, True, author='test@example.com'))
        + no_set()
        + does_not_clear()
    )

    yield (
        api.status_check.test('wrong-patchset')
        + properties()
        + unlabeled_query_results()
        + details(message(1, True))
        + no_set()
        + does_not_clear()
    )

    yield (
        api.status_check.test('dry-run')
        + properties(dry_run=True)
        + unlabeled_query_results()
        + details(message(2, True))
        + set_passed(dry_run=True)
        + does_not_clear()
    )

    yield (
        api.status_check.test('clear')
        + properties()
        + labeled_query_results()
        + no_set()
        + clear()
    )

    yield (
        api.status_check.test('clear-dryrun')
        + properties(dry_run=True)
        + labeled_query_results()
        + no_set()
        + clear(dry_run=True)
    )
