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

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

    repos = list(props.repo)

    # TODO(b/231587812) Remove transition code.
    if props.host and props.project and not repos:
        repos.append(
            'https://{}.googlesource.com/{}'.format(props.host, props.project)
        )

    projects_by_host = collections.defaultdict(list)
    for repo in repos:
        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 old_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 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-old')
        + old_properties()
        + unlabeled_query_results()
        + details(message(2, True))
        + set_passed()
        + does_not_clear()
    )

    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)
    )
