#!/usr/bin/env python3

import os
import re
import subprocess
import sys


RE_RELEVANT_FILE_EXTENSION = re.compile('\\.(cpp|h|gml|html|js|css|sh|py|json|txt)$')


def should_check_file(filename):
    if not RE_RELEVANT_FILE_EXTENSION.search(filename):
        return False
    if filename.startswith('Userland/Libraries/LibCodeComprehension/Cpp/Tests/'):
        return False
    if filename.startswith('Userland/Libraries/LibCpp/Tests/parser/'):
        return False
    if filename.startswith('Userland/Libraries/LibCpp/Tests/preprocessor/'):
        return False
    if filename == 'Kernel/FileSystem/Ext2FS/Definitions.h':
        return False
    if filename.endswith('.txt'):
        return 'CMake' in filename
    return True


def find_files_here_or_argv():
    if len(sys.argv) > 1:
        raw_list = sys.argv[1:]
    else:
        process = subprocess.run(["git", "ls-files"], check=True, capture_output=True)
        raw_list = process.stdout.decode().strip('\n').split('\n')

    return filter(should_check_file, raw_list)


def run():
    """Check files checked in to git for trailing newlines at end of file."""
    no_newline_at_eof_errors = []
    blank_lines_at_eof_errors = []

    did_fail = False
    for filename in find_files_here_or_argv():
        with open(filename, "r") as f:
            f.seek(0, os.SEEK_END)

            f.seek(f.tell() - 1, os.SEEK_SET)
            if f.read(1) != '\n':
                did_fail = True
                no_newline_at_eof_errors.append(filename)
                continue

            while True:
                f.seek(f.tell() - 2, os.SEEK_SET)
                char = f.read(1)
                if not char.isspace():
                    break
                if char == '\n':
                    did_fail = True
                    blank_lines_at_eof_errors.append(filename)
                    break

    if no_newline_at_eof_errors:
        print("Files with no newline at the end:", " ".join(no_newline_at_eof_errors))
    if blank_lines_at_eof_errors:
        print("Files that have blank lines at the end:", " ".join(blank_lines_at_eof_errors))

    if did_fail:
        sys.exit(1)


if __name__ == '__main__':
    os.chdir(os.path.dirname(__file__) + "/..")
    run()
