#!/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

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