#!/usr/bin/env python
# Copyright (c) 2012 OpenStack, LLC.
#
# 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
#
# http://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.

# This script is designed to expire old code reviews that have not been touched
# using the following rules:
# 1. if negative comment and no recent activity, expire

import argparse
import json
import logging
import paramiko

logger = logging.getLogger('expire_reviews')
logger.setLevel(logging.INFO)


def expire_patch_set(ssh, patch_id, patch_subject):
    message = ('Code review expired due to no recent activity'
               ' after a negative review. It can be restored using'
               ' the \`Restore Change\` button under the Patch Set'
               ' on the web interface.')
    command = ('gerrit review --abandon '
               '--message="{message}" {patch_id}').format(
                   message=message,
                   patch_id=patch_id)

    logger.info('Expiring: %s - %s: %s', patch_id, patch_subject, message)
    stdin, stdout, stderr = ssh.exec_command(command)
    if stdout.channel.recv_exit_status() != 0:
        logger.error(stderr.read())


def main():

    parser = argparse.ArgumentParser()
    parser.add_argument('user', help='The gerrit admin user')
    parser.add_argument('ssh_key', help='The gerrit admin SSH key file')
    parser.add_argument('--age', dest='age', default='1w',
                        help='The minimum age of a review to expire')
    options = parser.parse_args()

    GERRIT_USER = options.user
    GERRIT_SSH_KEY = options.ssh_key
    EXPIRY_AGE = options.age

    logging.basicConfig(format='%(asctime)-6s: %(name)s - %(levelname)s'
                               ' - %(message)s',
                        filename='/var/log/gerrit/expire_reviews.log')

    logger.info('Starting expire reviews')
    logger.info('Connecting to Gerrit')

    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect('localhost', username=GERRIT_USER,
                key_filename=GERRIT_SSH_KEY, port=29418)

    # Query all reviewed with no activity for 1 week
    logger.info('Searching no activity on negative review for 1 week')
    stdin, stdout, stderr = ssh.exec_command(
        'gerrit query --current-patch-set --all-approvals'
        ' --format JSON status:reviewed age:' + EXPIRY_AGE)

    for line in stdout:
        row = json.loads(line)
        if 'rowCount' not in row:
            # Search for negative approvals
            for approval in row['currentPatchSet']['approvals']:
                if approval['value'] in ('-1', '-2'):
                    expire_patch_set(ssh,
                                     row['currentPatchSet']['revision'],
                                     row['subject'])
                    break

    logger.info('End expire review')

if __name__ == "__main__":
    main()
