#!/usr/bin/env python3
#
# Copyright © 2019 Endless Mobile, Inc.
#
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# Original author: Philip Withnall

"""
Checks that a merge request doesn’t add any instances of the string ‘todo’
(in uppercase), or similar keywords. It may remove instances of that keyword,
or move them around, according to the logic of `git log -S`.
"""

import argparse
import re
import subprocess
import sys


# We have to specify these keywords obscurely to avoid the script matching
# itself. The keyword ‘fixme’ (in upper case) is explicitly allowed because
# that’s conventionally used as a way of marking a workaround which needs to
# be merged for now, but is to be grepped for and reverted or reworked later.
BANNED_KEYWORDS = [
    "TO" + "DO",
    "X" + "XX",
    "W" + "IP",
]


def main():
    parser = argparse.ArgumentParser(
        description="Check a range of commits to ensure they don’t contain "
        "banned keywords."
    )
    parser.add_argument("commits", help="SHA to diff from, or range of commits to diff")
    args = parser.parse_args()

    banned_words_seen = set()
    seen_in_log = False
    seen_in_diff = False

    # Check the log messages for banned words.
    log_process = subprocess.run(
        ["git", "log", "--no-color", args.commits + "..HEAD"],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        encoding="utf-8",
        check=True,
    )
    log_lines = log_process.stdout.strip().split("\n")

    for line in log_lines:
        for keyword in BANNED_KEYWORDS:
            if re.search(r"(^|\W+){}(\W+|$)".format(keyword), line):
                banned_words_seen.add(keyword)
                seen_in_log = True

    # Check the diff for banned words.
    diff_process = subprocess.run(
        ["git", "diff", "-U0", "--no-color", args.commits],
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        encoding="utf-8",
        check=True,
    )
    diff_lines = diff_process.stdout.strip().split("\n")

    for line in diff_lines:
        if not line.startswith("+ "):
            continue

        for keyword in BANNED_KEYWORDS:
            if re.search(r"(^|\W+){}(\W+|$)".format(keyword), line):
                banned_words_seen.add(keyword)
                seen_in_diff = True

    if banned_words_seen:
        if seen_in_log and seen_in_diff:
            where = "commit message and diff"
        elif seen_in_log:
            where = "commit message"
        elif seen_in_diff:
            where = "commit diff"

        print(
            "Saw banned keywords in a {}: {}. "
            "This indicates the branch is a work in progress and should not "
            "be merged in its current "
            "form.".format(where, ", ".join(banned_words_seen))
        )
        sys.exit(1)


if __name__ == "__main__":
    main()
