#!/usr/bin/env python
#
# 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 is designed to be called by a gerrit hook.  It searched new
# patchsets for those from a first time commiter, then posts a helpful
# message welcoming them to the community and explaining the review process
#
# For example, this might be called as follows
# python welcome_message.py --change Ia1fea1eab3976f1a9cb89ceb3ce1c6c6a7e79c42
# --change-url \ https://review-dev.openstack.org/81 --project gtest-org/test \
# --branch master --uploader User A. Example (user@example.com) --commit \
# 05508ae633852469d2fd7786a3d6f1d06f87055b --patchset 1 patchset-merged \
# --ssh-user=user --ssh-key=/home/user/.ssh/id_rsa
# and if this was the first commit from "user@example.com", a message
# would be posted on review 81.


import argparse
import logging
import paramiko

import jeepyb.gerritdb
import jeepyb.log as l

BASE_DIR = '/home/gerrit2/review_site'

logger = logging.getLogger('welcome_reviews')


def is_newbie(uploader):
    """Determine if the owner of the patch is a first-timer."""

    # Retrieve uploader email
    try:
        searchkey = uploader[uploader.rindex("(") + 1:-1]
    except ValueError:
        logger.info('Couldnt get email for %s', uploader)
        return False

    # this query looks for all distinct patchsets for the given
    # user. If there's only 1, they're a first-timer.
    query = """SELECT COUNT(DISTINCT p.change_id + p.patch_set_id)
               FROM patch_sets p, account_external_ids a
               WHERE a.email_address = %s
               AND a.account_id = p.uploader_account_id;"""

    cursor = jeepyb.gerritdb.connect().cursor()
    cursor.execute(query, searchkey)
    data = cursor.fetchone()
    if data:
        if data[0] == 1:
            logger.info('We found a newbie: %s', uploader)
            return True
        else:
            return False


def post_message(commit, gerrit_user, gerrit_ssh_key, message_file):
    """Post a welcome message on the patch set specified by the commit."""

    default_text = """\
Congratulations, you've proposed your first change in OpenDev.

Your submission will now be tested automatically by Zuul, our gatekeeper,
and reviewed by other friendly developers. They will give you feedback and
may require you to refine it.

People seldom get their patch approved on the first try, so don't be
concerned if requested to make corrections. Feel free to modify your patch
and resubmit a new change-set.

Patches often take days (and sometimes weeks) to get reviewed, so be
patient. Don't hesitate to ask for help, and answer questions about your
work promptly if you can. The more you get to know reviewers and get to be
known by them, the smoother the review and approval process will become. The
fastest way to accomplish this is by reviewing other proposed changes
yourself: anybody can do it, and it's a great way to learn the code base.

Thanks again for participating in OpenDev, we look forward to seeing you
around.

Workflow Guide: https://docs.openstack.org/infra/manual/developers.html
"""

    if message_file:
        try:
            with open(message_file, 'r') as _file:
                welcome_text = _file.read()
        except (OSError, IOError):
            logger.exception("Could not open message file")
            welcome_text = default_text
    else:
        welcome_text = default_text

    # post the above message, using ssh.
    command = ('gerrit review '
               '--message="{message}" {commit}').format(
                   message=welcome_text,
                   commit=commit)
    logger.info('Welcoming: %s', commit)
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect('localhost', username=gerrit_user,
                key_filename=gerrit_ssh_key, port=29418)
    stdin, stdout, stderr = ssh.exec_command(command)
    stdout_text = stdout.read()
    stderr_text = stderr.read()
    ssh.close()
    if stdout_text:
        logger.debug('stdout: %s' % stdout_text)
    if stderr_text:
        logger.error('stderr: %s' % stderr_text)


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('hook')
    # common
    parser.add_argument('--change', default=None)
    parser.add_argument('--change-url', default=None)
    parser.add_argument('--project', default=None)
    parser.add_argument('--branch', default=None)
    parser.add_argument('--commit', default=None)
    parser.add_argument('--topic', default=None)
    parser.add_argument('--change-owner', default=None)
    # patchset-abandoned
    parser.add_argument('--abandoner', default=None)
    parser.add_argument('--reason', default=None)
    # change-merged
    parser.add_argument('--submitter', default=None)
    parser.add_argument('--newrev', default=None)
    # patchset-created
    parser.add_argument('--uploader', default=None)
    parser.add_argument('--patchset', default=None)
    parser.add_argument('--is-draft', default=None)
    parser.add_argument('--kind', default=None)
    # for Welcome Message
    parser.add_argument('--ssh-user', dest='ssh_user',
                        help='The gerrit welcome message user')
    parser.add_argument('--ssh-key', dest='ssh_key',
                        help='The gerrit welcome message SSH key file')
    parser.add_argument('--message-file', dest='message_file', default=None,
                        help='The gerrit welcome message')
    # Don't actually post the message
    parser.add_argument('--dryrun', dest='dryrun', action='store_true')
    parser.add_argument('--no-dryrun', dest='dryrun', action='store_false')
    parser.set_defaults(dryrun=False)
    l.setup_logging_arguments(parser)

    args = parser.parse_args()

    l.configure_logging(args)

    # they're a first-timer, post the message on 1st patchset
    if is_newbie(args.uploader) and args.patchset == '1' and not args.dryrun:
        post_message(args.commit, args.ssh_user, args.ssh_key,
                     args.message_file)

if __name__ == "__main__":
    main()
