# 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 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, label, cq_account, project, dry_run):
    project_part = ''
    if project:
        project_part = 'project:{} '.format(project)

    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=project_part,)

    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
            )

            if project and project != details['project']:
                continue

            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, label, cq_account, project, dry_run):
    project_part = ''
    if project:
        project_part = 'project:{} '.format(project)

    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=project_part,)

    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)
    assert re.match(r'^[-\w./_]*$', props.project)

    actions = []

    with api.step.defer_results():
        actions.extend(
            _label_completed_unlabelled(
                api=api,
                host=props.host,
                label=props.label,
                cq_account=props.cq_account,
                project=props.project,
                dry_run=props.dry_run,
            )
        )

        actions.extend(
            _remove_running_labelled(
                api=api,
                host=props.host,
                label=props.label,
                cq_account=props.cq_account,
                project=props.project,
                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 = {
            'host': 'pigweed',
            'project': 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(
            'get unlabeled changes',
            api.json.output([{'_number': 1, 'project': project}]),
        )

    def labeled_query_results(project='pigweed'):
        return api.step_data(
            '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('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, '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,
            '1.{}set {} to -1'.format(dry_run_part, label),
        )

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

    def does_not_clear(label=VERIFIED_LABEL):
        return api.post_process(
            post_process.DoesNotRun, '1.clear {}'.format(label),
        ) + api.post_process(
            post_process.DoesNotRun, '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, '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('wrong-project')
        + properties()
        + unlabeled_query_results()
        + details(message(2, True), project='chromium')
        + 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)
    )
