#!/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 is designed to be called by a gerrit hook.  It searched new
# patchsets for strings like "bug FOO" and updates corresponding Launchpad
# bugs status.

# You want to test this? I use a command line a bit like this:
#     python notify_impact.py --change 55607 \
#     --change-url https://review.openstack.org/55607 --project nova/ \
#     --branch master --commit c262de4417d48be599c3a7496ef94de5c84b188c \
#     --impact DocImpact --dest-address none@localhost --dryrun \
#     --config foo.yaml \
#     change-merged
#
# But you'll need a git repository at /home/gerrit2/review_site/git/nova.git
# for that to work

from __future__ import print_function

import argparse
import os
import re
import smtplib
import subprocess

from email.mime import text
from launchpadlib import launchpad
from launchpadlib import uris
import yaml

from jeepyb import projects

BASE_DIR = '/home/gerrit2/review_site'
EMAIL_TEMPLATE = """
Hi, I'd like you to take a look at this patch for potential
%s.
%s

Log:
%s
"""

GERRIT_CACHE_DIR = os.path.expanduser(
    os.environ.get('GERRIT_CACHE_DIR',
                   '~/.launchpadlib/cache'))
GERRIT_CREDENTIALS = os.path.expanduser(
    os.environ.get('GERRIT_CREDENTIALS',
                   '~/.launchpadlib/creds'))


class BugActionsReal(object):
    """Things we do to bugs."""

    def __init__(self, lpconn):
        self.lpconn = lpconn

    def create(self, project, bug_title, bug_descr, args):
        buginfo = self.lpconn.bugs.createBug(
            target=project, title=bug_title,
            description=bug_descr, tags=args.project.split('/')[1])
        buglink = buginfo.web_link
        return buginfo, buglink

    def subscribe(self, buginfo, subscriber):
        user = self.lpconn.people[subscriber]
        if user:
            buginfo.subscribe(person=user)


class BugActionsDryRun(object):
    def __init__(self, lpconn):
        self.lpconn = lpconn

    def create(self, project, bug_title, bug_descr, args):
        print('I would have created a bug in %s, but I am in dry run mode.\n\n'
              'Title: %s\n'
              'Description:\n'
              '%s' % (project, bug_title, bug_descr))
        return None, None

    def subscribe(self, buginfo, subscriber):
        print('I would have added %s as a subscriber to the bug, '
              'but I am in dry run mode' % subscriber)


def create_bug(git_log, args, config):
    """Create a bug for a change.

    Create a launchpad bug in a LP project, titled with the first line of
    the git commit message, with the content of the git_log prepended
    with the Gerrit review URL. Tag the bug with the name of the repository
    it came from. Returns link to the bug.
    """

    # Determine what LP project to use
    prelude = ''
    project_name = args.project.rstrip('/')
    lp_project = projects.docimpact_target(project_name)
    if lp_project == 'unknown':
        prelude = ('\n\nDear documentation bug triager. This bug was created '
                   'here because we did not know how to map the project name '
                   '"%s" to a launchpad project name. This indicates that the '
                   'notify_impact config needs tweaks. You can ask the '
                   'OpenStack infra team (#openstack-infra on freenode) for '
                   'help if you need to.\n'
                   % args.project)
        lp_project = 'openstack-manuals'

    lpconn = launchpad.Launchpad.login_with(
        'Gerrit User Sync',
        uris.LPNET_SERVICE_ROOT,
        GERRIT_CACHE_DIR,
        credentials_file=GERRIT_CREDENTIALS,
        version='devel')

    if args.dryrun:
        actions = BugActionsDryRun(lpconn)
    else:
        actions = BugActionsReal(lpconn)

    lines_in_log = git_log.split('\n')
    bug_title = lines_in_log[4]
    bug_descr = args.change_url + prelude + '\n' + git_log
    project = lpconn.projects[lp_project]

    buglink = None
    author_class = None

    buginfo, buglink = actions.create(project, bug_title, bug_descr, args)

    # If the author of the merging patch matches our configured
    # subscriber lists, then subscribe the configured victims.
    for email_address in config.get('author_map', {}):
        email_re = re.compile('^Author:.*%s.*' % email_address)
        for line in bug_descr.split('\n'):
            m = email_re.match(line)
            if m:
                author_class = config['author_map'][email_address]

    if author_class:
        config = config.get('subscriber_map', {}).get(author_class, [])
        for subscriber in config:
            actions.subscribe(buginfo, subscriber)

    return buglink


def process_impact(git_log, args, config):
    """Process DocImpact flag.

    If the 'DocImpact' flag is present for a change that is merged,
    create a new documentation bug in
    the openstack-manuals launchpad project based on the git_log.
    For non-documentation impacts at all states of merge
    notify the mailing list of impact.
    """
    if args.impact.lower() == 'docimpact':
        if args.hook == "change-merged":
            create_bug(git_log, args, config)
        return

    email_content = EMAIL_TEMPLATE % (args.impact,
                                      args.change_url, git_log)

    msg = text.MIMEText(email_content)
    msg['Subject'] = '[%s] %s review request change %s' % \
        (args.project, args.impact, args.change)
    msg['From'] = 'gerrit2@review.openstack.org'
    msg['To'] = args.dest_address

    s = smtplib.SMTP('localhost')
    s.sendmail('gerrit2@review.openstack.org',
               args.dest_address, msg.as_string())
    s.quit()


def impacted(git_log, impact_string):
    """Determine if a changes log indicates there is an impact."""
    return re.search(impact_string, git_log, re.IGNORECASE)


def extract_git_log(args):
    """Extract git log of all merged commits."""
    cmd = ['git',
           '--git-dir=' + BASE_DIR + '/git/' + args.project + '.git',
           'log', '--no-merges', args.commit + '^1..' + args.commit]
    return subprocess.Popen(cmd, stdout=subprocess.PIPE).communicate()[0]


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)

    # change-merged
    parser.add_argument('--submitter', default=None)

    # patchset-created
    parser.add_argument('--uploader', default=None)
    parser.add_argument('--patchset', default=None)
    parser.add_argument('--is-draft', default=None)

    # Not passed by gerrit:
    parser.add_argument('--impact', default=None)
    parser.add_argument('--dest-address', default=None)

    # Automatic config: config contains a mapping of email addresses to
    # subscribers.
    parser.add_argument('--config', type=argparse.FileType('r'),
                        default=None)

    # Don't actually create the bug
    parser.add_argument('--dryrun', dest='dryrun', action='store_true')
    parser.add_argument('--no-dryrun', dest='dryrun', action='store_false')
    parser.set_defaults(dryrun=False)

    args = parser.parse_args()

    # NOTE(mikal): the basic idea here is to let people watch
    # docimpact bugs filed by people of interest. For example
    # my team's tech writer wants to be subscribed to all the
    # docimpact bugs we create. The config for that would be
    # something like:
    #
    # author_map:
    #     mikal@stillhq.com: rcbau
    #     grumpy@dwarves.com: rcbau
    #
    # subscriber_map:
    #     rcbau: ['mikalstill', 'grumpypants']
    #
    # Where the entries in the author map are email addresses
    # to match in author lines, and the subscriber map is a
    # list of launchpad user ids.
    config = {}
    if args.config:
        config = yaml.load(args.config.read())

    # Get git log
    git_log = extract_git_log(args)

    # Process impacts found in git log
    if impacted(git_log, args.impact):
        process_impact(git_log, args, config)

if __name__ == "__main__":
    main()
