# 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
from RECIPE_MODULES.fuchsia.auto_roller.api import (
    FAILED_DRY_RUN_MESSAGES,
    PASSED_DRY_RUN_MESSAGES,
)

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

PROPERTIES = InputProperties


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,
):
    project_part = ' OR '.join(f'project:{p}' for p in projects)
    query_string = (
        f'is:open '
        f'-(label:Commit-Queue+1 OR label:Commit-Queue+2) '
        f'-(label:{label}-1 OR label:{label}+1) '
        f'(r:{cq_account} OR cc:{cq_account}) '
        f'({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
            ] = f'https://{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

                if not message['message'].startswith(f'Patch Set {patch}:'):
                    continue

                for msg in PASSED_DRY_RUN_MESSAGES:
                    if msg in message['message']:
                        with api.step.nest('passed'):
                            value = 1
                            break

                for msg in FAILED_DRY_RUN_MESSAGES:
                    if msg in message['message']:
                        with api.step.nest('failed'):
                            value = -1
                            break

                if value:
                    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):
    project_part = ' OR '.join('project:{}'.format(p) for p in projects)
    query_string = (
        f'is:open '
        f'(label:Commit-Queue+1 OR label:Commit-Queue+2) '
        f'(label:{label}-1 OR label:{label}+1) '
        f'(r:{cq_account} OR cc:{cq_account}) '
        f'({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
            ] = f'https://{api.gerrit.normalize_host(host)}/{change_id}'

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

            else:
                action = f'clear {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': [f'https://pigweed.googlesource.com/{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):
        passfail = FAILED_DRY_RUN_MESSAGES[0]
        if passed:
            passfail = PASSED_DRY_RUN_MESSAGES[0]

        return {
            'author': {'email': author,},
            'message': f'Patch Set {patch_set}: {passfail}',
        }

    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, f'pigweed.1.{dry_run_part}set {label} to 1',
        )

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

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

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

    def clear(label=VERIFIED_LABEL, dry_run=False):
        dry_run_part = 'would ' if dry_run else ''
        return api.post_process(
            post_process.MustRun, f'pigweed.1.{dry_run_part}clear {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)
    )
