#!/usr/bin/env python3
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

import argparse
import re
import sys

from git import Repo

error_msg_prefix = 'ERROR: '
warning_msg_prefix = 'WARNING: '

# Maximum length of the summary line in the commit message (the first line)
# There is no hard limit, but a typical convention is to keep this line at or
# below 50 characters, with occasional outliers.
COMMIT_MSG_MAX_SUMMARY_LEN = 100


def error(msg, commit=None):
    full_msg = msg
    if commit:
        full_msg = "Commit %s: %s" % (commit.hexsha, msg)
    print(error_msg_prefix + full_msg, file=sys.stderr)


def warning(msg, commit=None):
    full_msg = msg
    if commit:
        full_msg = "Commit %s: %s" % (commit.hexsha, msg)
    print(warning_msg_prefix + full_msg, file=sys.stderr)


def lint_commit_author(commit):
    success = True
    if commit.author.email.endswith('users.noreply.github.com'):
        error(
            'Commit author has no valid email address set: %s. '
            'Use "git config user.email user@example.com" to '
            'set a valid email address, then update the commit '
            'with "git rebase -i" and/or '
            '"git commit --amend --reset-author". '
            'Also check your GitHub settings at '
            'https://github.com/settings/emails: your email address '
            'must be verified, and the option "Keep my email address '
            'private" must be disabled.' % (commit.author.email, ), commit)
        success = False

    if ' ' not in commit.author.name:
        warning(
            'The commit author name "%s" contains no space. '
            'Use "git config user.name \'Johnny English\'" to '
            'set your real name, and update the commit with "git rebase -i " '
            'and/or "git commit --amend --reset-author".' %
            (commit.author.name, ), commit)
        # A warning doesn't fail lint.

    return success


def lint_commit_message(commit):
    success = True
    lines = commit.message.splitlines()

    # Check length of summary line.
    summary_line_len = len(lines[0])
    if summary_line_len > COMMIT_MSG_MAX_SUMMARY_LEN:
        error(
            "The summary line in the commit message is %d characters long; "
            "only %d characters are allowed." %
            (summary_line_len, COMMIT_MSG_MAX_SUMMARY_LEN), commit)
        success = False

    # Check for an empty line separating the summary line from the long
    # description.
    if len(lines) > 1 and lines[1] != "":
        error(
            "The second line of a commit message must be empty, as it "
            "separates the summary from the long description.", commit)
        success = False

    # Check that the commit message contains at least one Signed-off-by line
    # that matches the author name and email. There might be other signoffs (if
    # there are multiple authors). We don't have any requirements about those
    # at the moment and just pass them through.
    signoff_lines = []
    signoff_pfx = 'Signed-off-by: '
    for idx, line in enumerate(lines):
        if not line.startswith(signoff_pfx):
            continue

        signoff_body = line[len(signoff_pfx):]
        match = re.match(r'[^<]+ <[^>]*>$', signoff_body)
        if match is None:
            error('Commit has Signed-off-by line {!r}, but the second part '
                  'is not of the required form. It should be of the form '
                  '"Signed-off-by: NAME <EMAIL>".'
                  .format(line))
            success = False

        signoff_lines.append(line)

    expected_signoff_line = ("Signed-off-by: {} <{}>"
                             .format(commit.author.name,
                                     commit.author.email))
    signoff_req_msg = ('The commit message must contain a Signed-off-by line '
                       'that matches the commit author name and email, '
                       'indicating agreement to the Contributor License '
                       'Agreement. See CONTRIBUTING.md for more details. '
                       'You can use "git commit -s" to ask git to add this '
                       'line for you.')

    if not signoff_lines:
        error('Commit has no Signed-off-by line. ' + signoff_req_msg)
        success = False
    elif expected_signoff_line not in signoff_lines:
        error(('Commit has one or more Signed-off-by lines, but not the one '
               'we expect. We expected to find "{}". '
               .format(expected_signoff_line)) +
              signoff_req_msg)
        success = False

    return success


def lint_commit(commit):
    success = True
    if not lint_commit_author(commit):
        success = False
    if not lint_commit_message(commit):
        success = False
    return success


def main():
    global error_msg_prefix
    global warning_msg_prefix

    parser = argparse.ArgumentParser(
        description='Check commit metadata for common mistakes')
    parser.add_argument('--error-msg-prefix',
                        default=error_msg_prefix,
                        required=False,
                        help='string to prepend to all error messages')
    parser.add_argument('--warning-msg-prefix',
                        default=warning_msg_prefix,
                        required=False,
                        help='string to prepend to all warning messages')
    parser.add_argument('--no-merges',
                        required=False,
                        action="store_true",
                        help='do not check commits with more than one parent')
    parser.add_argument('commit_range',
                        metavar='commit-range',
                        help=('commit range to check '
                              '(must be understood by git log)'))
    args = parser.parse_args()

    error_msg_prefix = args.error_msg_prefix
    warning_msg_prefix = args.warning_msg_prefix

    lint_successful = True

    repo = Repo()
    commits = repo.iter_commits(args.commit_range)
    for commit in commits:
        print("Checking commit %s" % commit.hexsha)
        is_merge = len(commit.parents) > 1
        if is_merge and args.no_merges:
            print("Skipping merge commit.")
            continue

        if not lint_commit(commit):
            lint_successful = False

    if not lint_successful:
        error('Commit lint failed.')
        sys.exit(1)


if __name__ == '__main__':
    main()
