#!/usr/bin/python

#       Licensed to the Apache Software Foundation (ASF) under one
#       or more contributor license agreements.  See the NOTICE file
#       distributed with this work for additional information
#       regarding copyright ownership.  The ASF licenses this file
#       to you 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.

import re
import sys

signoff = re.compile('^Signed-off-by: (.*)$', flags=re.MULTILINE)
bug = re.compile('\[(?:.*:)?#\d+\]')


def deny_commit(message):
    print message
    sys.exit(1)


def main():
    # argv[1] is the name of the file holding the commit message.
    # It is _not_ a commit, it has no headers.  The first line is
    # the subject.
    with open(sys.argv[1]) as commit_msg:
        subject = commit_msg.readline()

        if not bug.search(subject):
            deny_commit('Commit subject must reference a ticket.')

        number_of_signoffs = 0
        signoffs = set()
        for line in commit_msg.readlines():
            match = signoff.match(line)
            # comment lines won't match signoff, so we effectively ignore them
            if match:
                number_of_signoffs += 1
                signoffs.add(match.group(1))

    # must be at least one sign-off
    if not len(signoffs):
        deny_commit('Commit must be signed-off.')

    # and every sign-off must be different
    if len(signoffs) < number_of_signoffs:
        deny_commit('Duplicate sign-offs found.')

if __name__ == '__main__':
    main()
