# 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'].get('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)

    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(
        repo=(f'https://pigweed.googlesource.com/{PROJECT}'),
        cq_account=CQ_BOT_ACCOUNT,
        label=VERIFIED_LABEL,
        dry_run=False,
    ):
        if isinstance(repo, str):
            repo = [repo]

        return api.properties(
            repo=list(repo),
            cq_account=cq_account,
            label=label,
            dry_run=dry_run,
        )

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