#!/usr/bin/env python3
#
# 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.
#

# Original: https://github.com/apache/arrow/blob/4dbce607d50031a405af39d36e08cd03c5ffc764/cpp/build-support/run_clang_format.py
# ChangeLog:
#     2018-01-08: Accept multiple source directories (@Licht-T)

import fnmatch
import os
import subprocess
import sys

if len(sys.argv) < 5:
    sys.stderr.write("Usage: %s $CLANG_FORMAT $CHECK_FORMAT exclude_globs.txt "
                     "$source_dir1 $source_dir2\n" %
                     sys.argv[0])
    sys.exit(1)

CLANG_FORMAT = sys.argv[1]
CHECK_FORMAT = int(sys.argv[2]) == 1
EXCLUDE_GLOBS_FILENAME = sys.argv[3]
SOURCE_DIRS = sys.argv[4:]

exclude_globs = [line.strip() for line in open(EXCLUDE_GLOBS_FILENAME, "r")]

files_to_format = []
matches = []
for source_dir in SOURCE_DIRS:
    for directory, subdirs, files in os.walk(source_dir):
        for name in files:
            name = os.path.join(directory, name)
            if not (name.endswith('.h') or name.endswith('.cc') or name.endswith('.c')):
                continue

            excluded = False
            for g in exclude_globs:
                if fnmatch.fnmatch(name, g):
                    excluded = True
                    break
            if not excluded:
                files_to_format.append(name)

if CHECK_FORMAT:
    output = subprocess.check_output([CLANG_FORMAT, '-output-replacements-xml']
                                     + files_to_format,
                                     stderr=subprocess.STDOUT).decode('utf8')

    to_fix = []
    for line in output.split('\n'):
        if 'offset' in line:
            to_fix.append(line)

    if len(to_fix) > 0:
        print("clang-format checks failed, run 'make format' to fix")
        sys.exit(-1)
else:
    try:
        cmd = [CLANG_FORMAT, '-i'] + files_to_format
        subprocess.check_output(cmd, stderr=subprocess.STDOUT)
    except Exception as e:
        print(e)
        print(' '.join(cmd))
        raise