#!/usr/bin/env python
# Copyright (c) 2011 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 "blueprint FOO" or "bp FOO" and updates
# corresponding Launchpad blueprints with links back to the change.

from launchpadlib.launchpad import Launchpad
from launchpadlib.uris import LPNET_SERVICE_ROOT
import os
import argparse
import re
import subprocess

import StringIO
import ConfigParser
import MySQLdb

BASE_DIR = '/home/gerrit2/review_site'
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'))
GERRIT_CONFIG = os.environ.get('GERRIT_CONFIG',
                               '/home/gerrit2/review_site/etc/gerrit.config')
GERRIT_SECURE_CONFIG_DEFAULT = '/home/gerrit2/review_site/etc/secure.config'
GERRIT_SECURE_CONFIG = os.environ.get('GERRIT_SECURE_CONFIG',
                                      GERRIT_SECURE_CONFIG_DEFAULT)
SPEC_RE = re.compile(r'(blueprint|bp)\s*[#:]?\s*(\S+)', re.I)
BODY_RE = re.compile(r'^\s+.*$')


def get_broken_config(filename):
    """ gerrit config ini files are broken and have leading tabs """
    text = ""
    with open(filename, "r") as conf:
        for line in conf.readlines():
            text = "%s%s" % (text, line.lstrip())

    fp = StringIO.StringIO(text)
    c = ConfigParser.ConfigParser()
    c.readfp(fp)
    return c

GERRIT_CONFIG = get_broken_config(GERRIT_CONFIG)
SECURE_CONFIG = get_broken_config(GERRIT_SECURE_CONFIG)
DB_USER = GERRIT_CONFIG.get("database", "username")
DB_PASS = SECURE_CONFIG.get("database", "password")
DB_DB = GERRIT_CONFIG.get("database", "database")


def update_spec(launchpad, project, name, subject, link, topic=None):
    # For testing, if a project doesn't match openstack/foo, use
    # the openstack-ci project instead.
    group, project = project.split('/')
    if group != 'openstack':
        project = 'openstack-ci'

    spec = launchpad.projects[project].getSpecification(name=name)
    if not spec:
        return

    if spec.whiteboard:
        wb = spec.whiteboard.strip()
    else:
        wb = ''
    changed = False
    if topic:
        topiclink = '%s/#q,topic:%s,n,z' % (link[:link.find('/', 8)],
                                            topic)
        if topiclink not in wb:
            wb += "\n\n\nGerrit topic: %(link)s" % dict(link=topiclink)
            changed = True

    if link not in wb:
        wb += ("\n\n\nAddressed by: {link}\n"
               "    {subject}\n").format(subject=subject,
                                         link=link)
        changed = True

    if changed:
        spec.whiteboard = wb
        spec.lp_save()


def find_specs(launchpad, dbconn, args):
    git_dir_arg = '--git-dir={base_dir}/git/{project}.git'.format(
        base_dir=BASE_DIR,
        project=args.project)
    git_log = subprocess.Popen(['git', git_dir_arg, 'log', '--no-merges',
                                args.commit + '^1..' + args.commit],
                               stdout=subprocess.PIPE).communicate()[0]

    cur = dbconn.cursor()
    cur.execute("select subject, topic from changes where change_key=%s",
                args.change)
    subject, topic = cur.fetchone()
    specs = set([m.group(2) for m in SPEC_RE.finditer(git_log)])

    if topic:
        topicspec = topic.split('/')[-1]
        specs |= set([topicspec])

    for spec in specs:
        update_spec(launchpad, args.project, spec, subject,
                    args.change_url, topic)


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)
    #change-merged
    parser.add_argument('--submitter', default=None)
    # patchset-created
    parser.add_argument('--uploader', default=None)
    parser.add_argument('--patchset', default=None)

    args = parser.parse_args()

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

    conn = MySQLdb.connect(user=DB_USER, passwd=DB_PASS, db=DB_DB)

    find_specs(launchpad, conn, args)
